Program stacji XF-551 wygenerowany na podstawie pliku moja_XF551.bin.

Przyporzdkowanie wyprowadze portw:

P1.7 - ~DATA IN
P1.6 - ~SIDE z connectora FDD
P1.5 - R/~W z kontrolera
P1.4 - ~MR (Master Reset) z kontrolera
P1.3 - ~DDEN (Double Density Enable) z kontrolera
P1.2 - INTRQ (Interrupt Request) z kontrolera
P1.1 - A1 z WD1772
P1.0 - A0 z WD1772

P2.7 - przecznik Drive Select 1
P2.6 - przecznik Drive Select 2
P2.5 i P2.4 - ustalany wewntrznie format dyskietki. Dostpne wartoci: %00 - DD, %01 - DSDD, %10 - SD, %11 - ED
P2.3 - A11 dla pamici Eprom
P2.2 - A10 dla pamici Eprom
P2.1 - A9 dla pamici Eprom
P2.0 - A8 dla pamici Eprom

int - Command
T0 - zanegowane DATA OUT
T1 - DRQ z kontrolera (Data Request)

STRESZCZENIE:

Procesor 8040 znajdujcy si w stacji XF-551 taktowany jest zegarem 8.333 MHz.
Czstotliwo ta jest dzielona wewntrznie przez 3. Kady cykl maszynowy zajmuje 5 taktw zegara po podziale przez 3.
Instrukcje procesora zajmuj 1 lub 2 takty maszynowe.
A zatem odmierzajc dugo bitu dla prdkoci 19200 potrzebujemy wykonac: 8333000/3/5/19200 = 28.9 cykli maszynowych.
A dla prdkoci 38400 okoo 14 cykli, co oznacza tak wanie liczb instrukcji nop (kada zajmuje 1 cykl).

Licznik taktowany jest sygnaem zegarowym podzielony przez 3 * 5 * 32. Przepenienie licznika nastpuje wic co 3 * 5 * 32 / 8333000 = 1/68 sek.
Opnienie z licznikiem ciasnej ptli inicjowanym na 035H odpowiada okoo 200 us.

Stacja XF-551 rozpoznaje 8 rnych polece: '!', '"', 'N', 'O', 'S', 'P', 'R' i 'W'.
Kade z polece moe by w trybie zwykym i w trybie Turbo - wwczas jego kod zwiksza si o 128.
Niezalenie jednak od tego, czy Turbo jest wczone czy nie, cztery bajty polecenia + suma kontrola oraz wysyane potwierdzenie nadawane s zawsze
w trybie Normal.

--- Gstoci i przeploty

Gsto: SD, Normal
01 03 05 07 09 11 13 15 17 02 04 06 08 10 12 14 16 18
Przeplot: 9, 10

Gsto: ED, Normal
01 03 05 07 09 11 13 15 17 19 21 23 25 02 04 06 08 10 12 14 16 18 20 22 24 26
Przeplot: 13, 14

Gsto: DD, Normal
01 07 13 06 12 18 05 11 17 04 10 16 03 09 15 02 08 14
Przeplot: 15, 16

Gsto: DD, Turbo
01 03 05 07 09 11 13 15 17 02 04 06 08 10 12 14 16 18
Przeplot: 9, 10

Gsto: DSDD, Normal, druga strona
18 12 06 13 07 01 14 08 02 15 09 03 16 10 04 17 11 05

Gsto: DSDD, Turbo, druga strona
18 16 14 12 10 08 06 04 02 17 15 13 11 09 07 05 03 01

Tylko w gstociach DD i DSDD wystpuje rnica przy formacie w Turbo

--- Formaty cieek

Opis okrela, jakie bajty stacja wysya do kontrolera przy formatowaniu cieek.

Format cieki w gstoci SD:

 46 00
------- POCZTEK SEKTORA
  1 fe  ID Address Mark
  1 14  Nr cieki
  1 00  Strona
  1 01  Nr sektora
  1 00  Kod dugoci sektora
  1 f7  Zapis 2 bajtw CRC
 17 00
  1 fb  Data Address Mark
128 ff  Dane sektora
  1 f7  Zapis 2 bajtw CRC
 18 00
------- KONIEC SEKTORA
 95 00

Odstp przed pocztkiem pierwszego sektora: 46
Dugo sektora: 173
Odstp za ostatnim sektorem: 95

Format cieki w gstoci ED:

 60 4e
------- POCZTEK SEKTORA
 12 00
  3 f5  Zapisz a1, zresetuj CRC
  1 fe  ID Address Mark
  1 14  Nr cieki
  1 00  Strona
  1 01  Nr sektora
  1 00  Kod dugoci sektora
  1 f7  Zapis 2 bajtw CRC
 22 4e
 12 00
  3 f5  Zapisz a1, zresetuj CRC
  1 fb  Data Address Mark
128 ff  Dane sektora
  1 f7  Zapis 2 bajtw CRC
 24 4e
------- KONIEC SEKTORA
886 4e

Odstp przed pocztkiem pierwszego sektora: 60
Dugo sektora: 214
Odstp za ostatnim sektorem: 886

Format cieki w gstoci DD:

 60 4e
------- POCZTEK SEKTORA
 12 00
  3 f5  Zapisz a1, zresetuj CRC
  1 fe  ID Address Mark
  1 14  Nr cieki
  1 00  Strona
  1 01  Nr sektora
  1 01  Kod dugoci sektora
  1 f7  Zapis 2 bajtw CRC
 22 4e
 12 00
  3 f5  Zapisz a1, zresetuj CRC
  1 fb  Data Address Mark
256 ff  Dane sektora
  1 f7  Zapis 2 bajtw CRC
 24 4e
------- KONIEC SEKTORA
294 4e

Odstp przed pocztkiem pierwszego sektora: 60
Dugo sektora: 342
Odstp za ostatnim sektorem: 294

--- Lista polece:

--- POLECENIE 'S' (GET STATUS):

W odpowiedzi przesyane s 4 bajty:

Bajt 1 - okrela przyjt gsto dyskietki: $80 (ED), $60 (DSDD), $20 (DD) lub $00 (SD) + warto wewntrznego bajtu
         statusu na 4 najmodszych bajtach
Bajt 2 - jeeli kontroler nie jest w stanie Reset, to jest to bajt statusu z odwrconymi bitami z ustawionym bitem 7.
         Jeeli kontroler jest w stanie Reset, wwczas bajtem tym jest $ff
Bajt 3 - maksymalny czas wykonania komendy rwny $fe
Bajt 4 - jest rwny 0

Dopuszczalne wartoci wewntrznego bajtu statusu:

0 - ok
1 - nierozpoznanie polecenia
2 - przesany ostatnio blok by bdny
4 - niepowodzenie operacji
c - zabezpieczenie dyskietki przed zapisem


--- POLECENIE 'N' (READ PERCOM):

Zwracane jest blok 12 bajtw w zalenoci od ustawionej wewntrznie gstoci:

dla SD:   28 00 00 12 00 00 00 80 01 41 00 00
dla ED:   28 00 00 1a 00 04 00 80 01 41 00 00
dla DD:   28 00 00 12 00 04 01 00 01 41 00 00
dla DSDD: 28 00 00 12 01 04 01 00 01 41 00 00

Znaczenie bajtw:

Bajt 1  - liczba cieek na dyskietce ($28)
Bajt 2  - szybko przesuwu gowicy ze ciezki na ciek - 30 ms (0)
Bajt 3  - starszy bajt liczby sektorw na ciece (0)
Bajt 4  - modszy bajt liczby sektorw na ciece ($12 lub $1a)
Bajt 5  - liczba stron dyskietki - 1 ($00 lub $01)
Bajt 6  - gsto FM ($00) lub MFM ($04)
Bajt 7  - starszy bajt wielkoci sektora ($00 lub $80)
Bajt 8  - modszy bajt wielkoci sektora ($80 lub $00)
Bajt 9  - zawsze rwny $01
Bajt 10 - zawsze rwny $41
Bajt 11 - zawsze rwny 0
Bajt 12 - zawsze rwny 0


--- POLECENIE 'O' (WRITE PERCOM):

Pobiera 12-bajtowy blok danych PERCOM, po czym ustawiana jest gsto wewntrzna oraz gsto kontrolera na podstawie
modszego bajtu liczby sektorw na dyskietce (bajtu nr 4), liczby stron dyskietki - 1 (bajtu nr 5) i starszego bajtu wielkoci sektora
(bajtu nr 7).


--- POLECENIE '!' (FORMAT) i '"' (FORMAT ENHANCED)

Za pomoc polecenia '!' dyskietka formatowana jest w gstociach SD, DD lub DSDD.
Jeeli format wewntrzny ustawiony jest na ED, wwczas jest on przestawiany jest na SD.
Polecenie '"' formatuje dyskietk zawsze w gstoci rozszerzonej i na t gsto ustawia format wewntrzny.

W odpowiedzi na polecenia '!' i '"' przesyane jest zawsze tyle bajtw, jaka bya dugo sektora.
Jeeli formatowanie jest prawidowe, wwczas w gstociach SD i ED pierwsze 4 bajty maj warto $ff, pozostae maj
warto przypadkow. Dla gstoci DD i DSDD 4 pierwsze bajty maj warto $00, $ff, $ff, $ff.
Jeeli formatowanie jest bdne, wwczas dla kadej gstoci pierwsze 4 bajty maj wartoci $00, $00, $ff, $ff.

Bd formatowania moe powsta w trakcie weryfikacji, ktra odczytuje po kolei zawarto wszystkiech sektorw na ciekach.
Jeeli przekroczony zostanie czas podczas odczytu danych, wwczas ustawiany jest znacznik bdu i formatowanie jest
przerywane. W przypadku poprawnego formatowania bajtem potwierdzenia po zakoczonej operacji (przed wysaniem bloku danych)
jest 'C', w przypadku bdu 'E'.

Bajty DAUX1 i DAUX2 nie wpywaj na sam proces formatowania, jednak gdy ustawione s one na $10 i $50 stacja wykona
nastpujce czynnoci:

- jeeli nie wystpi bd formatowania, stacja bdzie je przeprowadzaa w kko
- jeeli wystpi bd formatowania, nie zostanie zwrcona adna odpowied do komputera


--- POLECENIA 'R', 'P' i 'W'

Polecenia do odczytu i zapisu sektora. Ich sposb dziaania zaley nieco od tego, czy stacja znajduje si w trybie
rozpoznawania gstoci czy nie. Dane sektora zapisywane s na dyskietce w takiej samej kolejnoci, w jakiej zostay odebrane, jednak
w postaci zanegowanej.


--- Tre programu stacji

Uwaga do opisu: WIELKIMI LITERAMI opisana jest nazwa funkcji, ktr realizuje fragment rozpoczynajcy si z danego miejsca


0000   sel     mb0          wybr pierwszego bloku pamici i skok na pocztek programu
0001   jmp     L0100

; Pocztek procedury przerwania zewntrznego wywoywanego przez lini COMMAND

0003   sel     rb0          pierwszy blok pamici i piewszy zestaw rejestrw
0004   sel     mb0
0005   jmp     L002A        do waciwej procedury

; Pocztek procedury przerwania powodowanego przez timer

0007   sel     mb0          pierwszy zestaw rejestrw
0008   dis     tcnti        wyczenie przerwa timera i jego zatrzymanie
0009   stop    tcnt
000A   call    L00C8        skok do pustej procedury
000C   -L000C:
000C   mov     r0,#07BH     na wypadek problemu z odbiorem polcenia, ustaw w wewntrznym bajcie statusu kod
000E   mov     @r0,#002H    oznaczajcy oznaczajcy "przesany ostatnio blok by bdny"
0010   -L0010:              CZEKAJ NA NASTPNE POLECENIE
0010   mov     r7,#0CCH     bdziemy czekali przez $cc przepenie licznika
0012   strt    t            wcz timer
0013   anl     p2,#0F8H		wyzeruj trzy najmodsze bity p2, co oznacza, e nie rozpoczto obsugi adnego polecenia
0015   en      i
0016   -L0016:              oczekuj na przepenienie timera i po jego wystpieniu skocz do $001A
0016   jtf     L001A        jeeli nastpio przepenienie - przeskakujemy i kasujemy flag przerwania
0018   jmp     L0016        czekaj na przepenienie

001A   -L001A:
001A   djnz    r7,L0016
001C   -L001C:
001C   anl     p1,#0DCH     odczyt STATUS REGISTER kontrolera
001E   orl     p1,#020H
0020   movx    a,@r0
0021   cpl     a            odwrcenie bajtw
0022   -L0022:
0022   jb7     L0028        jeeli kontroler jest "READY" -> 028 (wieczna ptla, wyjcie tylko poprzez przerwanie spowodowane przez lini Command)
0024   anl     p2,#0F7H     oznacza, e przy odczycie / zapisie gowica ma zosta przesunita na ciek 0 w celu ustalenia gstoci
0026   anl     p1,#0EFH     Master Reset kontrolera = 0
0028   -L0028:
0028   jmp     L0028        wieczna ptla, wyjcie tylko poprzez przerwanie spowodowane przez lini Command

002A   -L002A:              WACIWA PROCEDURA WYKONYWANA PO AKTYWACJI LINII COMMAND
002A   anl     p1,#07FH     ustawienie DATA IN
002C   dis     tcnti        wyczenie przerwa i licznika
002D   dis     i            wycz przerwania
002E   call    L00C8        skok do pustej procedury
0030   in      a,p2       \
0031   anl     a,#007H    | jeeli trzy najmodsze bity p2 s wyzerowane - nie rozpoczto obsugi adnego polecenia -> omi Force Interrupt
0033   jz      L0050      /
0035   mov     r0,#07BH   \ ustaw w wewntrznym statusie operacji kod oznaczajcy niepowodzenie operacji
0037   mov     @r0,#004H  /
0039   mov     r7,#0CCH     przez tyle przepenie licznika bdziemy czeka przed zawieszeniem si stacji
003B   strt    t            wczenie timera
003C   anl     p2,#0F8H     wyzeruj trzy najmodsze bity p2, co oznacza, e nie rozpoczto obsugi adnego polecenia
003E   xrl     a,#004H    \ jeeli by wykonywany ostatnio zapis PERCOM -> odczyt polecenia, ominicie Force Interrupt
0040   jz      L0050      /
0042   -L0042:
0042   xrl     a,#003H    \ (bit nr 2 jest odwrcony) jeeli by odczyt PERCOM lub sprawdzenie statusu -> odczyt polecenia, ominicie Force Interrupt
0044   jz      L0050      /
0046   in      a,p1       \ sprawdzenie, czy ustawiony jest Master Reset
0047   anl     a,#010H    /
0049   jz      L0050        tak -> ominicie Force Interrupt
004B   anl     p1,#0DCH   \
004D   mov     a,#0D0H    | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
004F   movx    @r0,a      /
0050   -L0050:
0050   mov     r0,#079H     r0 - bajty bd zapisywane do komrek poczwszy od $79 w d
0052   mov     r1,#000H     r1 - suma kontrolna rwna 0
0054   mov     r2,#005H     r2 - 5 bajtw do przeczytania razem z sum kontroln
0056   -L0056:
0056   jni     L0066        jeeli przerwanie jest dalej wyzwalane (Command = 0) -> rozpocznij odbir
0058   jmp     L00BD        zawieszenie si, w oczekiwaniu na kolejne przerwanie

005A   -L005A:              ZAPISZ PRZECZYTANY Z DATAOUT bajt
005A   mov     @r0,a        zapis jest pod adres wskazywany przez r0
005B   dec     r0           zmniejsz o 1, aby wskazywa adres dla nastpnego bajtu
005C   add     a,r1         dodaj do obliczanej sumy kontrolnej w r1 razem z przepenieniem
005D   addc    a,#000H
005F   mov     r1,a         nowa suma kontrolna do r1
0060   mov     r3,#005H   \
0062   -L0062:            | wykonaj 5-obrotow ciasn ptl
0062   djnz    r3,L0062   /
0064   jt0     L009B        jeeli DATA OUT = 0 -> brak bitu stopu, zignoruj polecenie
0066   -L0066:
0066   jnt0    L0056        jeeli DATA OUT = 1 (brak jeszcze bitu startu) -> czekaj
0068   mov     a,#080H      zainicjuj czytany bajt na $80, aby po przesuniciu go w prawo 8 razy, C byo rwne 1
006A   mov     r3,#007H   \
006C   -L006C:            | 7-obrotowa ciasna ptla
006C   djnz    r3,L006C   /
006E   -L006E:              kontynuuj czytanie bitw z DATA OUT
006E    nop
006F    mov    r3,#008H   \
0071    -L0071:           | ptla opniajca
0071    djnz   r3,L0071   /

0073   -L0073:              CZYTAJ BIT Z DATAOUT
0073   clr     c            domylnie 0
0074   jt0     L0079        jeli T0=1 (czyli DATA OUT=0), to przeskocz do nopw
0076   cpl     c            C = 1
0077   jmp     L007C        omi nopy, jeli C=1

0079   -L0079:
0079   nop                  nopy s po to, aby uzyska t sam liczb cykli przy odczycie 0 i 1
007A   nop
007B   nop
007C   -L007C:
007C   rrc     a            wpisz go z lewej strony A
007D   jnc     L006E        jeeli z do C = 0 (nie przeczytano jeszcze 8 bitw), to kontynuuj czytanie bitw (L006E)
007F   djnz    r2,L005A     jeeli liczba bajtw do przeczytania jest rna od 0, to zapisz odczytany bajt (L005A)
0081   xrl     a,r1         czy odczytany bajt rwny jest obliczonej sumie kontrolnej w r1?
0082   jnz     L009B        nie -> czekaj na koniec nadawania, omi polecenie
0084   nop
0085   mov     r3,#006H   \
0087   -L0087:            | 6-obrotowa ciasna ptla
0087   djnz    r3,L0087   /
0089   jt0     L009B        jeeli DATA OUT = 0 (brak bitu stopu) -> zaczekaj na Command = 1
008B   jni     L008F        jeeli dalej Command = 0 -> realizacja
008D   jmp     L00BD        zawieszenie si, w oczekiwaniu na kolejne przerwanie

008F   -L008F:
008F   in      a,p2         we z portu 2 bity, ktre okrelaj numer wybranej stacji
0090   anl     a,#0C0H
0092   rl      a            przesu w lewo, aby bit 7 (jeden ze wskanikw wybranej stacji) przeszed do bitu  1
0093   rl      a
0094   add     a,#031H      po dodaniu do $31 otrzymujemy numer urzdzenia
0096   mov     r0,#079H     we do R0 numer urzdzenia - bajt spod $79 - adresu wypenionego bufora
0098   xrl     a,@r0        czy jest on rwny adresowi urzdzenia ustawionego za pomoc przecznikw stacji?
0099   jz      L009F        tak - przeskocz do obsugi polecenia
009B   -L009B:
009B   jni     L009B        zaczekaj na koniec wyzwalania przerwania (czyli na koniec stanu niskiego na linii COMMAND)
009D   jmp     L00BD        zawieszenie si, w oczekiwaniu na kolejne przerwanie

009F   -L009F:              OBSU POLECENIE DO STACJI DYSKW O USTAWIONYM PRZECZNIKAMI NUMERZE
009F   dec     r0           zmniejsz o 1 wskanik bufora polecenia, aby wskazywa na kod polecenia (2-gi bajt)
00A0   mov     a,@r0        we go do A
00A1   clr     f0           F0 = 0, co oznacza, e domylnie polecenie jest bez Turbo
00A2   rlc     a            bit nr 7 do C
00A3   jnc     L00A6        jeeli jest on rwny 0 - przeskok (nie ma polecenia Turbo)
00A5   cpl     f0           F0 = 1 - polecenie byo w trybie Turbo
00A6   -L00A6:              sprawd, czy stacja obsuguje polecenie o kodzie w r0
00A6   mov     r2,#008H     jest 8 polece
00A8   mov     r3,#0D0H     kody zapisane s od adresu $00D0 w d
00AA   -L00AA:
00AA   mov     a,r3         we kod polecenia spod adresu w R3
00AB   movp    a,@a
00AC   xrl     a,@r0        XOR z zawartoci R0
00AD   anl     a,#07FH      obetnij najstarszy bit
00AF   jz      L00D9        jeli s rwne -> $00D9 (rozpoznano polecenie)
00B1   dec     r3           zmniejsz o 1 adres nazwy polecenia
00B2   djnz    r2,L00AA     ptla a do pierwszego polecenia
00B4   -L00B4:              nie rozpoznano polecenia
00B4   mov     r0,#07BH   \
00B6   mov     a,#001H    | zapisz w wewntrznym bajcie statusu kod oznaczajcy nierozpoznanie polecenia
00B8   mov     @r0,a      /
00B9   mov     a,#04EH      transmitowanym znakiem do komputera bdzie 'A' (potwierdzenie przyjcia komendy)
00BB   call    L0207		przetransmituj bajt o kodzie w A
00BD   -L00BD:
00BD   en      i			wczenie przerwa
00BE   in      a,p1		  \ czy aktywny jest Master Reset kontrolera?
00BF   anl     a,#010H    /
00C1   jz      L0028        tak -> zawieszenie si programu, wyjcie tylko poprzez kolejne przerwanie
00C3   mov     a,r7			przepisz do A liczb przepenie licznika, przez ktre bdziemy czeka
00C4   jnz     L0016		czekaj przez okrelon liczb przepenie, po czym zawie program
00C6   jmp     L001C		zawie program, ale bez czekania
00C8   -L00C8:              pusta procedura wykonywana podczas aktywacji linii Command i przerwania timera
00C8   retr

; Tablica kodw obsugiwanych polece

00C9   db	   '!'          formatowanie dyskietki w ustawionej poprzednio gstoci
00CA   db      '"'          formatowanie dyskietki w gstoci rozszerzonej
00CB   db      'N'          odczyt PERCOM
00CC   db      'O'          zapis PERCOM
00CD   db      'S'          odczyt statusu
00CE   db      'P'          zapis sektora bez weryfikacji
00CF   db      'R'          odczyt sektora
00D0   db      'W'          zapisz sektora

; Tablica bajtw zawierajcych bity, ktre trzeba ustawi w p2 po wyborze danego polecenia.
; Ustawione w przypadku kadego polecenia bity 7 i 6 oznaczaj zezwolenie, aby sygnay Drive Select byy wejciami,
; ustawione bity 5 i 4 w przypadku polecenia '"' oznaczaj wymuszenie gstoci rozszerzonej a trzy najmodsze bity kadego polecenia oznaczaj jego kod.

00D1   db      0C5H 		'!' - ostatnie bity to 101
00D2   db      0F5H         '"' - ostatnie bity to 101
00D3   db      0C7H			'N' - ostatnie bity to 111
00D4   db      0C4H		  	'O' - ostatnie bity to 100
00D5   db      0C7H			'S' - ostatnie bity to 111
00D6   db      0C2H			'P' - ostatnie bity to 010
00D7   db      0C1H			'R' - ostatnie bity to 001
00D8   db      0C3H	 	    'W' - ostatnie bity to 011

00D9   -L00D9:				ROZPOZNANO POLECENIE
00D9   mov     a,r3         we do A adres kodu rozpoznanego polecenia
00DA   add     a,#008H      we do A warto z komrki dalszej o 8 bajtw (adres procedury obsugi)
00DC   movp    a,@a       \ adres ten zawiera bity, ktre naley ustawi w p2
00DD   mov     r1,a       /
00DE   in      a,p2       \
00DF   orl     a,r1       | wykonujemy orowanie w p2
00E0   outl    p2,a       /
00E1   mov     a,r2         we do A indeks polecenia z R2
00E2   add     a,#0E4H      dodaj $E4 - adres ostatniej komrki tej procedury
00E4   jmpp    @a           skocz pod adres w A w ramach danej strony

; Tabela modszych bajtw adresw, pod ktre naley skoczy, aby wykona dane polecenie

00E5   db 	   0EDH			modszy bajt adresu procedury formatowania dyskietki ('!')
00E6   db 	   0EFH			modszy bajt adresu procedury formatowania dyskieki w gstoci rozszerzonej ('"')
00E7   db 	   0F1H			modszy bajt adresu procedury odczytu PERCOM ('N')
00E8   db 	   0F3H			modszy bajt adresu procedury zapisu PERCOM ('O')
00E9   db 	   0F5H			modszy bajt adresu procedury odczytu statusu ('S')
00EA   db 	   0F7H			modszy bajt adresu procedury zapisu sektora bez weryfikacji ('P')
00EB   db 	   0F7H			modszy bajt adresu procedury odczytu sektora ('R')
00EC   db 	   0F7H			modszy bajt adresu procedury zapisu sektora z weryfikacj ('W')

00ED   jmp     L0500        skok do procedury formatowania dyskietki ('!')
00EF   jmp     L0512        skok do procedury formatowania dyskieki w gstoci rozszerzonej ('"')
00F1   jmp     L0400        skok do procedury odczytu PERCOM ('N')
00F3   jmp     L0458        skok do procedury zapisu PERCOM ('O')
00F5   jmp     L03AE        skok do procedury odczytu statusu ('S')
00F7   sel     mb1          skok do procedury zapisu sektora bez weryfikacji, odczytu sektora i zapisu sektora z weryfikacj ('P', 'R', 'W')
00F8   jmp     L0100		(jest to skok pod adres 0900)


; --- Start programu

0100   -L0100:
0100   dis     i          \ wycz przerwania i timer
0101   dis     tcnti      /
0102   mov     a,#02CH    \ R/~W = 1, ~DDEN=1, Interrupt Request jest wejciem, sygnay Drive Select 1 i 2 te s wejciami
0104   outl    p1,a       /
0105   mov     a,#0E0H    \ wybrana gsto to SD
0107   outl    p2,a       /
0108   sel     rb0          pierwszy zestaw rejestrw
0109   clr     f0           Turbo wyczone
010A   clr     f1           bdu do tej pory nie byo
010B   mov     r0,#07BH   \ wyzerowanie wewntrznego bajtu statusu
010D   mov     @r0,#000H  /
010F   mov     r0,#000H   \
0111   -L0111:            | ptla opniajca
0111   djnz    r0,L0111   /
0113   anl     p1,#0EFH     Master Reset kontrolera = 0
0115   mov     r0,#0F9H   \
0117   -L0117:            | ptla opniajca
0117   djnz    r0,L0117   /
0119   orl     p1,#010H     Master Reset kontrolera = 1
011B   anl     p1,#0DCH   \
011D   mov     a,#008H    | zapis do COMMAND REGISTER komendy RESTORE (Disable spin-up, No verify, 6ms)
011F   movx    @r0,a      /
0120   call    L013C        czekaj na Interrupt Request od kontrolera przez pewien czas
0122   mov     r1,#006H     ponisze polecenie wykonamy 6 razy (czyli dojdziemy do 6-tej cieki)
0124   -L0124:
0124   anl     p1,#0DCH   \
0126   mov     a,#048H    | zapis do COMMMAND REGISTER komendy STEP-IN (Update=0, disable spin-up, No Verify, 6ms)
0128   movx    @r0,a      /
0129   call    L013C        czekaj na Interrupt Request od kontrolera przez pewien czas
012B   djnz    r1,L0124     wykonaj 6-razy, do wyzerowania r1
012D   anl     p1,#0DCH   \
012F   mov     a,#008H    | zapis do COMMAND REGISTER komendy RESTORE (Disable spin-up, No verify, 6ms)
0131   movx    @r0,a      /
0132   call    L013C        czekaj na Interrupt Request od kontrolera przez pewien czas
0134   mov     a,#02CH    \ ustawienie DATA IN = 1, Master Reset = 1, ~DDEN = 1
0136   outl    p1,a       /
0137   orl     p2,#008H     omi rozpoznawanie gstoci na ciece 0 podczas wykonywania komend odczytu/zapisu sektora
0139   en      i            wcz przerwania

013A   -L013A:
013A   jmp     L013A        ptla oczekiwania na przerwanie

013C   -L013C:              OCZEKUJ NA INTERRUPT REQUEST PRZEZ PEWIEN CZAS
013C   mov     r0,#09CH     zaaduj liczb przepenie licznika, przez ktre bdziemy oczekiwa
013E   stop    tcnt         zatrzymaj timer i wyzeruj timer
013F   clr     a
0140   mov     t,a
0141   strt    t            uruchom timer
0142   jtf     L0144        wyzerowanie flagi przerwania od timera
0144   -L0144:
0144   in      a,p1         czy kontroler zasygnalizowa Interrupt Request?
0145   anl     a,#004H
0147   jz      L014A        nie (0 w INTRQ) -> przeskok
0149   ret                  wyjd - nastpi Interrupt Request

014A   -L014A:
014A   jtf     L014E        jeeli nastpio przepenienie licznika -> przeskok
014C   jmp     L0144        oczekuj dalej na Interrupt Request bd przepenienie licznika

014E   -L014E:              zmniejsz o 1 liczb przepenie licznika i kontynuuj czekanie
014E   djnz    r0,L0144
0150   stop    tcnt         zatrzymaj licznik
0151   ret

; Przetransmituj potwierdzenie przyjcia polecenia (znak 'A') w prdkoci podstawowej

0200   -L0200:
0200   stop    tcnt         zatrzymaj licznik i go wyzeruj
0201   clr     a
0202   -L0202:
0202   mov     t,a
0203   jtf     L0205        wyzerowanie flagi przerwania od timera
0205   -L0205:
0205   mov     a,#041H      we do a kod znaku 'A' (potwierdzenia)
0207   -L0207:
0207   clr     f1
0208   -L0208:              PRZETRANSMITUJ BAJT w A
0208   jni     L0208        wykonuj ciasn ptl, a zakoczy si wyzwalanie przerwania
020A   -L020A:
020A   orl     p1,#080H     ustaw DATA IN na 0
020C   clr     c
020D   cpl     c            ustawiamy C, ktre wejdzie jako ostatni bit - bit stopu
020E   -L020E:              instrukcje opniajce
020E   nop
020F   nop
0210   nop

0211   -L0211:
0211   nop					nastpny bit
0212   -L0212:
0212   mov     r6,#008H   \
0214   -L0214:            | wykonaj 8-obrotow, ciasn ptl
0214   djnz    r6,L0214   /
0216   -L0216:
0216   rrc     a            we do C bit do wytransmitowania (od najmodszego)
0217   jc      L021D        ustawiony -> L021D
0219   orl     p1,#080H     ustaw DATA IN, przeskocz dalej
021B   jmp     L0221

021D   -L021D:              wyzeruj DATA IN, przeskocz dalej
021D   anl     p1,#07FH
021F   jmp     L0221

0221   -L0221:				ustawiono bit to emisji
0221   clr     c            nastpny bit, ktry wejdzie na najstarsz pozycj, bdzie zerowy
0222   jnz     L0211        ptl wykonujemy a w A=0 (czyli przetransmitowalimy wszystko, cznie z bitem stopu)
0224   ret


; Odczytaj z DATA OUT liczb bajtw, ktrych zmniejszona o 1 liczba zapisana jest w r0 oraz bajt sumy kontrolnej. Odczyt moe by w Turbo lub nie i
; decyduje o tym F0. Odebrane bajty zapisywane s od adresu wskazywanego przez (r0) w d, z pominiciem komrki o adresie 0. Ostatni odebrany bajt
; przekazywany jest w t.

0225   -L0225:
0225   en      tcnti        wcz timer, aby wystpio przerwanie przy zbyt dugim odczycie
0226   strt    t
0227   -L0227:
0227   jnt0    L0227        zaczekaj na bit startu (T0 bdzie rwne 1)
0229   clr     a            A = 0 - nowa suma kontrolna, ktra zostanie za chwil przepisana do r1
022A   clr     f1
022B   nop
022C   nop
022D   jmp     L0239        skok do intrukcji, ktra zainicjuje sum kontroln i bdzie kontynuowaa odczyt

022F   -L022F:              ROZPOCZNIJ CZYTANIE NOWEGO BAJTU
022F   jt0     L02B3		nie ma bitu stopu -> skok do fragmentu oznaczajcego bdny blok
0231   -L0231:            \ czekaj na zakoczenie bitu stopu
0231   jnt0    L0231      /
0233   inc     r0		 	skok w to miejsce odbywa si po djnz, ktre zmniejsza r0 o 1. inc jest po to, aby zapis do pamici odbywa si od pocztkowego
0234   mov     @r0,a		indeksu r0 w d
0235   dec     r0			przywr poprzedni stan r0
0236   add     a,r1         dodaj A do sumy kontrolnej, ktr tworzymy w r1
0237   addc    a,#000H

0239   -L0239:				PO WYKRYCIU BITU STARTU
0239   mov     r1,a         zapamitaj now sum kontroln w r1
023A   -L023A:
023A   clr     a            wyzerowanie timera
023B   mov     t,a
023C   mov     a,#080H      A bdzie rwny $80. Po 8-miu przesuniciach w prawo C bdzie po raz pierwszy zawiera 1
023E   nop                  czekamy na rodek pierwszego bitu danych
023F   nop
0240   nop
0241   nop
0242   jf0     L0259        przeskocz nopy dla Turbo
0244   nop
0245   nop
0246   -L0246:

0246   nop					WYKONAJ OPӏNIENIE DO NASTPNEGO BITU DANYCH
0247   nop
0248   nop
0249   jf0     L0259        jeeli Turbo jest ustawione (F0=1), przeskocz dalej - bit jest krtszy
024B   nop                  Turbo jest wyczone, wic wykonujemy dodatkowe nopy opniajce
024C   nop
024D   nop
024E   nop
024F   nop
0250   nop
0251   nop
0252   nop

0253   -L0253:				CZYTANIE BITU DANYCH
0253   nop
0254   nop
0255   nop
0256   nop
0257   nop
0258   nop
0259   -L0259:              domylnie odbierany bit to 0
0259   clr     c
025A   jt0     L025F        jeeli T0=1 (DATA OUT=0) - przeskakujemy nastpne dwie instrukcje (C dobrze ustawione)
025C   cpl     c            odebrany bit to 1
025D   jmp     L0262

025F   -L025F:
025F   nop                  nopy, aby wyrwna liczb cykli
0260   nop
0261   nop
0262   -L0262:              przesu A w prawo, aby wpisa go jako najstarszy bit.
0262   rrc     a
0263   jnc     L0246        jeeli C=0 (bit stopu nie wszed jeszcze do najmodszego bitu -> kontynuacja odbierania

0265   jf0     L0275        jeeli wczone jest Turbo, to przeskakujemy nopy oznaczajce 1/2 bitu stopu dla prdkoci 19200s
0267   nop					14 nopw = 1/2 bitu w prdkoci 19200
0268   nop
0269   nop
026A   nop
026B   nop
026C   nop
026D   nop
026E   nop
026F   nop
0270   nop
0271   nop
0272   nop
0273   nop
0274   nop
0275   -L0275:				POOWA BITU STOPU
0275   jf1     L0284		F1=1 oznacza, e odebralimy ostatni bajt przed sum kontroln. Wwczas wyskakujemy z ptli.
0277   djnz    r0,L022F     zmniejsz o 1 liczb bajtw do przeczytania w R0. Jeeli <> 0 - $L022F (kontynuacja)

0279   jt0     L02B3		jeeli nie ma bitu stopu -> bdny blok
027B   -L027B:
027B   jnt0    L027B        zaczekaj na koniec bitu stopu (T0 bdzie rwne 1)
027D   xch     a,r1         dodaj do sumy kontrolnej w r1 odebrany wanie bajt w A
027E   add     a,r1
027F   addc    a,r0			(w r0 jest 0)
0280   mov     r0,a         przepisz do r0 dotychczasow sum kontroln (do przedostatniego bajtu danych)
0281   cpl     f1			oznacza, e za chwil bdziemy odbiera przedostatni bajt danych.
0282   jmp     L023A		skok na pocztek ptli odbierajcej. Poniewa r0=0, wic przedostatni bajt danych zapisze si pod adresem 1

0284   -L0284:				POOWA BITU STOPU PO OSTATNIM BAJCIE DANYCH
0284   clr     f1			ustaw F1=0, tak jak byo na pocztku
0285   nop
0286   jt0     L02B3		nie ma bitu stopu -> skok do fragmentu oznaczajcego bdny blok
0288   -L0288:            \ czekaj na zakoczenie bitu stopu
0288   jnt0    L0288      /
028A   stop    tcnt         zatrzymaj timer, wycz przerwania od niego i wyzeruj go
028B   dis     tcnti
028C   mov     t,a			do t przepisz ostatni bajt przed sum kontroln
028D   add     a,r0			obliczona suma kontrolna bdzie w A
028E   addc    a,#000H

0290   clr     c			POCZTEK SPRAWDZANIA SUMY KONTROLNEJ
0291   cpl     c			C=1 (bdzie to bit stopu sumy kontrolnej)
0292   nop					14 nopw, mniej wicej poowa bitu startu w 19200
0293   nop
0294   nop
0295   nop
0296   nop
0297   jf0     L02AE		skok, gdy Turbo
0299   nop
029A   -L029A:
029A   nop
029B   nop
029C   nop
029D   nop
029E   jf0     L02AE		skok, gdy Turbo
02A0   nop
02A1   nop
02A2   nop
02A3   nop
02A4   nop
02A5   nop
02A6   nop

02A7   -L02A7:				KONTYNUACJA DLA PRDKOCI 19200
02A7   nop					dodatkowe nopy omijajce bit startu sumy kontrolnej
02A8   nop
02A9   nop
02AA   nop
02AB   nop
02AC   nop
02AD   nop
02AE   -L02AE:
02AE   rrc     a			w C bdzie bit, jaki powinien by teraz odebrany
02AF   jc      L02B5		od 02B5 jest fragment obsugujcy bit o wartoci 1
02B1   jt0     L02B7		jeeli C=0 i T0=1 (DATA OUT=0) -> bit si zgadza
02B3   -L02B3:
02B3   jmp     L000C		przesany blok by bdny

02B5   -L02B5:
02B5   jt0     L02B3		jeeli C=1, ale T0=1 (DATA OUT=0) -> bdny blok
02B7   -L02B7:
02B7   clr     c			C=0 - bit ten bdzie wchodzi do A po kadym przesuniciu bitw
02B8   jnz     L029A		nie koniec -> skok na pocztek ptli

02BA   mov     r0,#088H   \ KONIEC ODBIERANIA
02BC   -L02BC:            | ptla opniajca
02BC   djnz    r0,L02BC   /
02BE   -L02BE:
02BE   mov     r0,#088H   \
02C0   -L02C0:            | druga ptla opniajca
02C0   djnz    r0,L02C0   /
02C2   orl     p1,#080H		bit startu potwierdzenia (DATA IN=0)
02C4   mov     a,#041H		potwierdzenie ('A')
02C6   clr     c		  \ C=1 (bit stopu)
02C7   cpl     c          /
02C8   nop
02C9   -L02C9:
02C9   nop
02CA   nop
02CB   jf0     L02D2		skok, gdy Turbo
02CD   nop
02CE   mov     r0,#006H   \
02D0   -L02D0:            | ptla opniajca
02D0   djnz    r0,L02D0   /
02D2   -L02D2:
02D2   rrc     a		 	wpisanie do C bitu, ktry bdziemy emitowa
02D3   jc      L02D9		C=1 -> przeskok
02D5   orl     p1,#080H		DATA_IN=0
02D7   jmp     L02DD		bit wysyany ustawiony

02D9   -L02D9:
02D9   anl     p1,#07FH		DATA OUT=1
02DB   jmp     L02DD		bit wysyany ustawiony

02DD   -L02DD:
02DD   clr     c			bit C=0 bdzie od tej pory wchodzi z lewej strony
02DE   jnz     L02C9		nie koniec -> skok na pocztek ptli wysyajcej bity
02E0   in      a,p2		  \ we 3 nieuywane bity p2 jako wskanik, gdzie naley wrci po procedurze
02E1   anl     a,#007H    /
02E3   xrl     a,#004H    \ jeeli trzy ostatnie bity b2 s rwne 4 -> przeskok
02E5   jz      L02EA      /
02E7   sel     mb1        \ skok do 972 - kontynuacja procedury czytajcej lub zapisujcej sektor, gdy b2=0 w p2
02E8   jmp     L0172      /
02EA   -L02EA:
02EA   jmp     L045E		453 - kontynuacja, gdy b2=1 w p2

; Emisja tablicy bajtw poprzedzona pozytywnym lub negatywnym potwierdzeniem, o ktrym decyduje F1. Emitowane s bajty od (r0) w gr do koca strony.

0300   -L0300:
0300   mov     a,psw      \
0301   orl     a,#001H    | ustawiamy bit 0 psw, co oznacza domylne negatywne potwierdzenie
0303   mov     psw,a      /

;                           NADANIE KODU 'E' lub 'C'
0304   mov     a,#045H      do A kod litery 'E' - negatywnego potwierdzenia caej operacji
0306   jf1     L030E        jeeli ustawiony jest bit F1 - przeskok (bdne potwierdzenie)
0308   mov     a,psw      \
0309   anl     a,#0FEH    | kasujemy bit 0 psw, co oznacza pozytywne potwierdzenie
030B   mov     psw,a      /
030C   mov     a,#043H      do A kod litery 'C' - pozytywnego potwierdzenia caej operacji
030E   -L030E:
030E   orl     p1,#080H     ustaw bit startu
0310   clr     c            C = 1, wejdzie on do A po obrocie w prawo. Gdy A bdzie rwne 0, to koniec zapisu
0311   cpl     c
0312   nop
0313   nop
0314   nop
0315   -L0315:
0315   nop
0316   nop
0317   jf0     L0328        jeeli Turbo, to przeskakujemy nopy (krtszy bit startu)
0319   nop                  nopy opniajce dla transmisji w Normalu
031A   nop
031B   nop
031C   nop
031D   nop
031E   nop
031F   nop
0320   nop
0321   nop
0322   nop
0323   nop
0324   -L0324:
0324   nop
0325   nop
0326   nop
0327   nop
0328   -L0328:
0328   rrc     a            obrt w prawo A
0329   jc      L032F        gdy C = 1 - przeskok (DATAIN = 1)
032B   -L032B:
032B   orl     p1,#080H     DATA IN = 0
032D   jmp     L0333

032F   -L032F:
032F   anl     p1,#07FH     DATA IN = 1
0331   jmp     L0333        ten jmp do nastpnej instrukcji jest po to, aby wyrwna liczb cykli przy 0 i 1

0333   -L0333:
0333   clr     c            C = 0, ktre bdzie wchodzi do A po obrocie w prawo
0334   jnz     L0315        jeeli A jest rne od zera, kontynuujemy nadawanie (nie wyemitowano wszystkich bitw)

;                           NADAWANIE KOLEJNYCH BAJTW zapisanych pod adresem w r0
0336   mov     a,r0       \
0337   dec     a          | adres z r0 do A. Jeeli jest on rwny 1, to skok do L03A5 (nadano ju sum kontroln)
0338   jz      L03A5      /
033A   inc     a			zwiksz A o 1, aby byo ustawione tak, jak na pocztku
033B   mov     r0,#0A4H   \
033D   -L033D:            | ptla opniajca
033D   djnz    r0,L033D   /
033F   mov     r0,#0A4H   \
0341   -L0341:            | druga ptla opniajca
0341   djnz    r0,L0341   /
0343   mov     r0,a         zapisanie do r0 poprzedniej wartoci, ktra zostaa nadpisana podczas ptli opniajcych
0344   jnz     L034D        jeeli w r0 bya warto niezerowa, to transmitujemy jeszcze dane z przed sum kontroln

;                           r0 = 0. Nadalimy wszystkie dane. Teraz czas na sum kontroln, ktr mamy w t.
0346   orl     p1,#080H     ustaw bit startu (DATA IN = 0)
0348   mov     a,t          trasmitowana suma kontrolna do A
0349   nop
034A   nop
034B   jmp     L0368		skok do fragmentu wykonujcego rzeczywist emisj bajtw

034D   -L034D:				POCZTEK NADAWANIA
034D   clr     a          \ w t bdzie przechowywana suma kontrolna, ktr inicjujemy na 0
034E   mov     t,a        /
034F   -L034F:
034F   jf0     L0360        jeeli F0 = 1 (wczone jest Turbo) -> skracamy dugo bitu
0351   nop
0352   nop
0353   nop
0354   nop
0355   nop
0356   nop
0357   nop
0358   nop
0359   nop
035A   nop
035B   nop
035C   nop
035D   nop
035E   nop
035F   nop
0360   -L0360:
0360   mov     a,t          suma kontrolna z t do A
0361   orl     p1,#080H		bit startu
0363   add     a,@r0      \
0364   addc    a,#000H    | dodaj bajt do sumy kontrolnej w t
0366   mov     t,a        /
0367   mov     a,@r0		we bajt do emisji
0368   -L0368:              C = 1 - ten bit znajdzie si w A jako najstarszy po obrocie w prawo
0368   clr     c            dla nastpnych bitw C ustawimy pniej na 0
0369   cpl     c
036A   jf0     L0381		emituj bit, skracajc jego dugo, gdy Turbo
036C   jmp     L0374

036E   -L036E:
036E   nop
036F   nop
0370   jf0     L0381        jeeli F0 = 1 (Turbo) - skracamy bit - skok do L0381 (emituj bit)
0372   jmp     L0374

0374   -L0374:              nopy opniajce
0374   nop
0375   nop
0376   nop
0377   nop
0378   nop
0379   nop
037A   nop
037B   nop
037C   nop
037D   nop
037E   nop
037F   nop
0380   nop
0381   -L0381:
0381   rrc     a            obrt w prawo, wpisanie C jako najstarszy bit
0382   jc      L0388        ustawienie DATA IN na podstawie C, ktre byo najmodszym bitem
0384   orl     p1,#080H     DATA IN = 0
0386   jmp     L038C

0388   -L0388:
0388   anl     p1,#07FH     DATA IN = 1
038A   jmp     L038C

038C   -L038C:
038C   clr     c            C = 0 wejdzie do A z lewej strony po obrocie
038D   jnz     L036E
038F   inc     r0           nastpna komrka do transmisji
0390   mov     a,r0         czy r0 osigno 0?
0391   jnz     L034F        nie -> L034F
0393   inc     r0			bdzie rwne 1 (suma kontrolna)
0394   mov     a,t			we do t sum kontroln
0395   jf0     L030E
0397   nop
0398   nop
0399   nop
039A   nop
039B   nop
039C   nop
039D   nop
039E   nop
039F   nop
03A0   nop
03A1   nop
03A2   nop
03A3   jmp     L030E		nadaj sum kontroln

03A5   -L03A5:
03A5   mov     a,psw      \ jeeli emitowalimy negatywne potwierdzenie (b0 ustawiony) -> przeskok
03A6   jb0     L03AC      /
03A8   mov     r0,#07BH     wyzerowanie wewntrznego bajtu statusu
03AA   mov     @r0,#000H
03AC   -L03AC:
03AC   jmp     L0010        czekaj na nastpne polecenie

; --- Procedura odczytu statusu  ---

03AE   -L03AE:
03AE   call    L0200        przetransmituj kod przyjcia polecenia ('A')
03B0   mov     r0,#088H   \
03B2   -L03B2:            | ptla opniajca
03B2   djnz    r0,L03B2   /
03B4   mov     r0,#088H   \
03B6   -L03B6:            | druga ptla opniajca
03B6   djnz    r0,L03B6   /
03B8   mov     r0,#0FCH     bajty opisujca status zapisywane s od $fc
03BA   mov     @r0,#000H    PIERWSZY BAJT STATUSU domylnie jest rwny 0
03BC   in      a,p1       \ czy ustawiona jest gsto podwjna kontrolera?
03BD   anl     a,#008H    /
03BF   jnz     L03CC        nie -> L03CC (nie wykonujemy dodatkowych testw)
03C1   mov     @r0,#080H	mamy wic gsto podwjn kontrolera
03C3   in      a,p2		  \ jeeli jest ustawiony bit 5, jest to ED i wtedy bajtem jest $80
03C4   jb5     L03CC      /
03C6   mov     @r0,#060H  \ a zatem bit 5 = 0. jeeli bit 4 = 0, wwczas jest to DSDD i bajtem jest $60
03C8   jb4     L03CC      /
03CA   mov     @r0,#020H 	jeeli bity 4 i 5 s zerami, wwczas jest to DD i zapisujemy $20

03CC   -L03CC:
03CC   mov     r1,#07BH     pobranie wewntrznego bajtu statusu spod $7b
03CE   mov     a,@r1
03CF   orl     a,@r0        suma logiczna z ustawionym wanie wstpnie bajtem pod @r0
03D0   mov     @r0,a        zapis pierwszego bajtu
03D1   inc     r0           DRUGI BAJT STATUSU
03D2   mov     @r0,#0FFH    domylnie jest rwny $ff
03D4   in      a,p1         sprawdzenie stanu Master Reset kontrolera
03D5   anl     a,#010H
03D7   jz      L03EA        jeeli jest on rwny 0 (jest reset), to jako drugi bajt bdzie rwny $ff
03D9   anl     p1,#0DCH   \
03DB   orl     p1,#020H   | odczyt do A bajtu statusu z kontrolera
03DD   movx    a,@r0      /
03DE   cpl     a            odwrcenie bitw
03DF   orl     a,#080H      ustaw bit 7 na 1, co oznacza, e stacja nie jest w trakcie wykonywania rozkazu
03E1   mov     @r0,a        zapis drugiego bajtu statusu
03E2   jb7     L03EA        jeeli ustawiony jest bit 7 (czyli Not Ready = 0) -> przeskok (zawsze si wykonuje)
03E4   dec     r0           jeeli Not Ready = 1 - ustawiamy w poprzednim bajcie bit 4 (krci si silnik)
03E5   mov     a,@r0
03E6   orl     a,#010H
03E8   mov     @r0,a
03E9   inc     r0
03EA   -L03EA:
03EA   inc     r0           TRZECI BAJT STATUSU (timeout) jest rwny 254
03EB   mov     @r0,#0FEH
03ED   inc     r0           CZWARTYM BAJTEM STATUSU jest 0
03EE   mov     @r0,#000H
03F0   mov     r0,#0FCH     bdziemy emitowa bajty bdce odpowiedzi zapisane od adresu $fc
03F2   clr     f1           F1 = 0 oznacza, wyemitujemy pozytywne potwierdzenie (C)
03F3   jmp     L0300        skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff

; --- Procedura odczytu PERCOM ---

0400   -L0400:
0400   call    L0200        przetransmituj kod przyjcia polecenia ('A')
0402   mov     r0,#088H   \
0404   -L0404:            | ptla opniajca
0404   djnz    r0,L0404   /
0406   mov     r0,#088H   \
0408   -L0408:            | druga ptla opniajca
0408   djnz    r0,L0408   /
040A   mov     r0,#0F4H     blok PERCOM do wytransmitowania utworzony bdzie od $f4
040C   mov     @r0,#028H    bajt 1 - liczba cieek na dyskietce - $28 (40)
040E   inc     r0           bajt 2 - szybko przesuwu gowicy ze cieki na ciek - 0 (30 ms)
040F   mov     @r0,#000H
0411   inc     r0           bajt 3 - starszy bajt liczby sektorw na ciece (0)
0412   mov     @r0,#000H
0414   inc     r0           ustalanie bajtu 4
0415   in      a,p2       \
0416   anl     a,#030H    | czy oba bity 4 i 5 portu p2 s rwne 1?
0418   xrl     a,#030H    /
041A   mov     @r0,#01AH    bajt 4 rwny domylnie $1a (26 sektorw)
041C   jz      L0420        jeeli oba bity 4 i 5 byy rwne 1, to przeskok - jest gsto rozszerzona
041E   mov     @r0,#012H    bajt 4 rwny $12 (18 sektorw) - gsto SD, DD lub DSDD
0420   -L0420:
0420   inc     r0           ustalanie bajtu 5 (liczby stron dyskietki zmniejszonych o 1)
0421   mov     @r0,#000H    jest on domylnie rwny 0 (1 strona)
0423   in      a,p2       \
0424   anl     a,#030H    | czy bity 4 i 5 p2 byy rwne 0 i 1?
0426   xrl     a,#010H    /
0428   jnz     L042C        nie -> przeskok (jest 1 strona)
042A   mov     @r0,#001H    s 2 strony (gsto DSDD)
042C   -L042C:
042C   inc     r0           bajt 6 - domylnie jest rwny 0 (gsto FM)
042D   mov     @r0,#000H
042F   in      a,p2       \
0430   anl     a,#030H    | czy pracujemy w gstoci SD?
0432   xrl     a,#020H    /
0434   jz      L0438        tak -> przeskok (zostawiamy domylne 0, ktre oznacza, e dysk jest w gstoci FM)
0436   mov     @r0,#004H    wpisujemy jako bajt 5 liczb 4, co oznacza, e dysk jest w gstoci MFM
0438   -L0438:
0438   inc     r0           bajt 7 - starszy bajt wielkoci sektora jest domylnie rwny 0
0439   mov     @r0,#000H
043B   inc     r0           ustalanie bajtu 8 - modszego bajtu wielkoci sektora
043C   mov     @r0,#080H    domylnie 128 bajtw
043E   in      a,p2         jeeli bit 5 portu p2 jest ustawiony, wwczas przeskok - nie ma gstoci podwjnej
043F   jb5     L0447
0441   dec     r0           starszy bajt (poprzednio zapisany na 0) ustawiamy na 1
0442   mov     @r0,#001H
0444   inc     r0           a modszy jako 0 - czyli razem 256 bajtw
0445   mov     @r0,#000H
0447   -L0447:
0447   inc     r0           bajt 9 jest zawsze rwny 1
0448   mov     @r0,#001H
044A   inc     r0           bajt 10 jest zawsze rwny $41
044B   mov     @r0,#041H
044D   -L044D:
044D   inc     r0           bajt 11 jest zawsze rwny 0
044E   mov     @r0,#000H
0450   inc     r0           bajt 12 jest zawsze rwny 0
0451   mov     @r0,#000H
0453   mov     r0,#0F4H     zapisywa bdziemy bajty z bufora $f4 - $ff, czyli cznie 12 bajtw + suma kontrolna
0455   clr     f1           F1=0, czyli bdzie poprawne potwierdzenie (C)
0456   -L0456:
0456   jmp     L0300        skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff

; --- Procedura zapisu PERCOM ---

0458   -L0458:
0458   call    L0200        przetransmituj kod przyjcia polecenia ('A')
045A   mov     r0,#00BH     odczytaj 11+1 bajtw konfiguracji + bajt sumy kontrolnej
045C   jmp     L0225

045E   -L045E:				KONTYNUACJA, GDY b2=1 w p2
045E   dis     i            wycz przerwania
045F   orl     p1,#008H     ustawienie Master Reset = 1
0461   anl     p2,#0CFH     wyzerowanie dwch bitw okrelajcych format dyskietki
0463   mov     r0,#008H   \
0465   mov     a,@r0      | czy liczba sektorw jest rwna 26 (bajt nr 4 zapisany pod adresem $8)?
0466   xrl     a,#01AH    /
0468   jz      L0478     	tak -> ustaw gsto ED
046A   mov     a,r5       	sprawdzenie starszego bajtu wielkoci sektora (bajt nr 7 zapisany pod adresem $5)
046B   jz      L0474      	jeeli 0 -> ustaw SD
046D   mov     a,r7 		sprawdzenie liczby stron dyskietki - 1 (bajt 5 zapisany pod adresem $7)
046E   jz      L047A		jeeli 0 -> przeskok (gsto podwjna kontrolera, DD)
0470   orl     p2,#010H		wybranie gstoci DSDD
0472   jmp     L047A		przeskok w miejsce, gdzie wybierana jest gsto podwjna kontrolera

0474   -L0474:
0474   orl     p2,#020H		ustawienie gstoci SD
0476   jmp     L047C		przeskok instrukcji ustawiajcej gsto podwjna kontrolera

0478   -L0478:
0478   orl     p2,#030H		ustawienie gstoci ED
047A   -L047A:
047A   anl     p1,#0F7H		~DDEN=0 - wczenie gstoci podwjnej kontrolera
047C   -L047C:
047C   clr     f1			bdzie pozytywne potwierdzenie
047D   en      i            wcz przerwania
047E   mov     r0,#088H   \
0480   -L0480:            | ptla opniajca
0480   djnz    r0,L0480   /
0482   inc     r0			r0=1 - procedura wywoywana poniej wyemituje tylko pozytywne potwierdzenie
0483   jmp     L0300        skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff


; --- Procedura formatowania dyskietki ---

0500   -L0500:
0500   in      a,p2         czy formatem dyskietki jest ED?
0501   anl     a,#030H
0503   xrl     a,#030H
0505   jnz     L0509        nie -> przeskok nastpnej instrukcji
0507   anl     p2,#0EFH		ustawienie gstoci SD
0509   -L0509:
0509   orl     p1,#008H		wyczenie gstoci podwjnej kontrolera
050B   in      a,p2         sprawd format dyskietki
050C   anl     a,#030H    \ czy SD?
050E   xrl     a,#020H    / tak -> przeskok wczenie podwjnej gstoci
0510   jz      L0514


; --- Procedura formatowania dyskietki w gstoci rozszerzonej ---

0512   -L0512:
0512   anl     p1,#0F7H     wcz podwjn gsto
0514   -L0514:
0514   call    L0200        przetransmituj kod przyjcia polecenia ('A')
0516   -L0516:
0516   anl     p2,#0F7H		oznacza, e przy operacjach odczytu/zapisu sektora gowica ma by przesunita na ciek 0 i ma by rozpoznana gsto
0518   anl     p1,#0EFH     Master Reset kontrolera = 0
051A   mov     r0,#088H   \
051C   -L051C:            | ptla opniajce
051C   djnz    r0,L051C   /
051E   orl     p1,#010H     Master Reset kontrolera = 1
0520   mov     r0,#088H   \
0522   -L0522:            | ptla opniajca
0522   djnz    r0,L0522   /
0524   anl     p1,#0DCH   \
0526   mov     a,#0D0H    | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
0528   movx    @r0,a      /
0529   mov     r0,#035H   \
052B   -L052B:            | ptla opniajca
052B   djnz    r0,L052B   /
052D   in      a,p2       \
052E   rl      a          | wpisanie do r3 bajtu z bitem 7 ustawionym tak, jak bit 5 pb2:
052F   rl      a          |	r3=0 (dla DD lub DSDD)
0530   anl     a,#080H    | r3=1 (dla SD lub ED)
0532   mov     r3,a       /
0533   mov     r0,#07BH   \ ustaw w wewntrznym bajcie statusu kod niepowodzenia operacji
0535   mov     @r0,#004H  /
0537   clr     f1			wskanik powodzenia = 0 (ok)
0538   -L0538:
0538   anl     p2,#0F7H		przy odczycie/zapisie sektora przesu gowic na ciek 0 i rozpoznaj gsto
053A   anl     p1,#0DCH   \ zapis do COMMAND REGISTER komendy RESTORE (Enable spin-up, No verify, 6ms)
053C   mov     a,#000H    | (wyzerowanie A0 i A1, R/~W=0 - zapis)
053E   movx    @r0,a      /
053F   mov     r0,#0CCH 	przez tyle przepenie licznika bdziemy czeka (ok 3 sek)
0541   clr     a          \
0542   mov     t,a        | wyzerowanie licznika i jego uruchomienie
0543   strt    t          /
0544   -L0544:
0544   jtf     L0560		licznik si przepeni -> zmniejsz liczb przepenie
0546   -L0546:
0546   in      a,p1       \ sprawdzenie Interrupt Requesta
0547   anl     a,#004H    /
0549   jz      L0544		jeeli go nie ma -> czekaj dalej
054B   stop    tcnt			zatrzymaj licznik
054C   anl     p1,#0DCH   \
054E   orl     p1,#020H   | zapis do COMMAND REGISTER komendy STEP (No update, Enable spin-up, No Verify, 6ms)
0550   movx    a,@r0      /	BD!!! - jestemy ju na ciece zerowej a tutaj jest odczyt bajtu do A, ktry nie zostanie uyty
0551   anl     p1,#0DCH   \
0553   orl     p1,#001H   | zapisz do TRACK REGISTER warto 0
0555   clr     a          |
0556   movx    @r0,a      /
0557   mov     r2,a			zerowy numer cieki jest rwnie umieszczany w r2
0558   anl     p1,#0BFH		~SIDE kontrolera=0 (pierwsza strona)
055A   mov     r0,#088H   \
055C   -L055C:            | ptla opniajca
055C   djnz    r0,L055C   /
055E   jmp     L0570		przeskok dalej (jesttemy na ciece 0)

0560   -L0560:				(licznik si przepeni)
0560   djnz    r0,L0546		ptla a do ostatniego przepenienia licznika
0562   -L0562:
0562   stop    tcnt			zatrzymanie licznika (nie byo Interrupt Requesta)
0563   anl     p1,#0DCH   \
0565   mov     a,#0D0H    | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
0567   movx    @r0,a      /
0568   mov     r0,#035H   \
056A   -L056A:            | ptla opniajca
056A   djnz    r0,L056A   /
056C   clr     f1			F1=1 (bd)
056D   cpl     f1
056E   jmp     L069F		udziel odpowiedzi na polecenie formatowania jeli trzeba

0570   -L0570:				POCZTEK PTLI FORMATUJCEJ CIEKI
0570   anl     p1,#0DCH   \
0572   orl     p1,#003H   | zapis do DATA REGISTER wartoci w r2 (numeru cieki)
0574   mov     a,r2       |
0575   movx    @r0,a      /
0576   anl     p2,#0F7H		przy odczycie/zapisie przesu gowic na ciek 0 i rozpoznaj gsto
0578   anl     p1,#0DCH   \
057A   mov     a,#018H    | zapis do COMMAND REGISTER komendy SEEK (Enable Spin-up, No Verify, 6ms)
057C   movx    @r0,a      /
057D   clr     a          \ wyzerowanie timera
057E   mov     t,a        /
057F   jtf     L0581        wyzerowanie flagi przerwania od timera
0581   -L0581:
0581   mov     r0,#044H		liczba dopuszczalnych przepenie licznika w oczekiwaniu na Interrupt Request (ok 1 sek)
0583   strt    t			uruchomienie licznika
0584   -L0584:
0584   jtf     L0593		jeeli przepenienie -> zmniejsz liczb przepenie
0586   -L0586:
0586   in      a,p1		  \ odczyt Interrupt Request z kontrolera
0587   anl     a,#004H    /
0589   jz      L0584		nie ma -> czekaj dalej
058B   stop    tcnt			by Interrupt Request, zatrzymanie licznika
058C   anl     p1,#0DCH   \
058E   orl     p1,#020H   | zapis do Command Register polecenia RESTORE, ale z jakiego powodu R/~W kontrolera ustawiono na R - BD!!!
0590   movx    @r0,a      /
0591   jmp     L0597		przejcie dalej (jestemy na waciwej ciece)

0593   -L0593:				(przepenienie licznika)
0593   djnz    r0,L0586		zmniejsz o 1 liczb dopuszczalnych przepenie licznika i kontynuuj
0595   jmp     L0562		Force Interrupt i bd

0597   -L0597:				JESTEMY NA WACIWEJ CIECE
0597   mov     r4,#012H		18 sektorw na ciek
0599   mov     r5,#0F7H		przeplot 9 (domylny dla Turbo) w kodzie uzupenieniowym
059B   in      a,p2	      \ jeeli SD lub ED -> przeskok
059C   jb5     L05A4      /
059E   jf0     L05A2		jeeli wczone jest Turbo -> przeskok (ju ustawilimy liczb sektorw i przeplot)
05A0   mov     r5,#0F1H		przeplot 15 w kodzie uzupenieniowym
05A2   -L05A2:
05A2   jmp     L05AB		przeskok do czci zasadniczej ustalajcej kolejno sektorw. Gsto podwjna jednostronna lub dwustronna.

05A4   -L05A4:				SD lub ED
05A4   in      a,p1			we wskanik gstoci podwjnej kontrolera
05A5   jb3     L05AB		jeeli gsto pojedycza -> przeskok (bdzie SD)
05A7   mov     r4,#01AH		26 sektorw na ciek
05A9   mov     r5,#0F3H		przeplot 13 w kodzie uzupenieniowym
05AB   -L05AB:
05AB   mov     a,r4       \ w r0 umie liczb sektorw
05AC   mov     r0,a       /
05AD   add     a,#07FH    \ oblicz w r6 i r1 adres ostatniej komrki na numer sektora na ciece z uwzgldnieniem przeplotu.
05AF   mov     r6,a       |	Tablica sektorw zaczyna si od $80 w gr
05B0   mov     r1,a       /
05B1   -L05B1:
05B1   mov     @r1,#000H  \
05B3   dec     r1         | wyzeruj tablic sektorw
05B4   mov     a,r1       |
05B5   jb7     L05B1      /
05B7   -L05B7:
05B7   mov     a,r6       \ we do r6 adres ostatniej komrki i przeskocz do rodka ptli ustalajcej kolejno sektorw
05B8   jmp     L05BF      /

05BA   -L05BA:
05BA   mov     a,r1       \ dodaj przeplot (ujemny) z r5
05BB   add     a,r5       /
05BC   -L05BC:
05BC   jb7     L05BF		jeeli wynik na wci ustawiony najstarszy bit -> ok (numer komrki jest prawidowy)
05BE   add     a,r4			dodaj liczb sektorw
05BF   -L05BF:				RODEK PTLI USTALAJCEJ KOLEJNO SEKTORW
05BF   mov     r1,a			wstaw do r1 numer ustalonej komrki
05C0   mov     a,@r1		sprawdzenie, czy miejsce pod r1 jest puste
05C1   jz      L05C7		tak -> zapisanie numeru sektora
05C3   dec     r1         \
05C4   mov     a,r1       | zmniejszenie numeru komrki sektora o 1, kontunuacja ptli
05C5   jmp     L05BC      /

05C7   -L05C7:
05C7   in      a,p1			sprawdzenie ~SIDE
05C8   anl     a,#040H	  \ jeeli ~SIDE=1 (druga strona) -> przeskok (umer sektora jest prawidowo ustawiony)
05CA   jnz     L05D3      /
05CC   mov     a,r0			we indeks ptli, ktry zmienia si od maksymalnej liczby sektorw do 1
05CD   cpl     a          \ dodaj liczb sektorw, co powoduje, e numery sektorw na pierwszej stronie numerowane s odwrotnie
05CE   add     a,r4       |	np. dla 26 sektorw na ciece, sektor nr 26 otrzymuje numer 26 + (255 - 26) + 2 = 1
05CF   add     a,#002H    /
05D1   jmp     L05D4		zapis numeru sektora

05D3   -L05D3:
05D3   mov     a,r0       \
05D4   -L05D4:            | zapis pod adresem w r1 numer biecego sektora
05D4   mov     @r1,a      /
05D5   djnz    r0,L05BA		ptla a do ostatniego sektora
05D7   mov     a,r6       \ przepisz z r6 do r1 adres ostatniej komrki w tablicy rozmieszczenia sektorw na ciece
05D8   mov     r1,a       /
05D9   jmp     L0600		przeskok do czci zasadniczej formatowania albo weryfikacji

0600   -L0600:				CZʌ ZASADNICZA FORMATOWANIA I WERYFIKACJI
0600   jf1     L0633		jeeli jest to faza weryfikacji -> 633

; Single Density kontrolera

0602   mov     r4,#000H		bajt o takim kodzie zapisywany jest po F7
0604   mov     r5,#006H		liczba zer przed F5
0606   mov     r6,#00BH		liczba bajtw po pierwszym F7 o kodzie w r4
0608   mov     r7,#00CH		liczba bajtw po drugim F7 o kodzie w r4
060A   mov     r0,#027H		ile bajtw wypenienia midzy sektorami
060C   in      a,p1       \	jeeli nie wybrano Double Density kontrolera -> przeskok (parametry s ju ustawione)
060D   jb3     L0619      /

; Double Density kontrolera

060F   mov     r4,#04EH		bajt o takim kodzie zapisywany jest po F7
0611   mov     r5,#00CH		liczba zer przed F5
0613   mov     r6,#016H		liczba bajtw po pierwszym F7 o kodzie w r4
0615   mov     r7,#018H		liczba bajtw po drugim F7 o kodzie w r4
0617   mov     r0,#03BH		ile bajtw wypenienia midzy sektorami
0619   -L0619:
0619   mov     a,r2       \
061A   add     a,#0ECH    | ten fragment kodu zawsze koczy si przypisaniem F6 do A (kod Write Track, Enable Spin-up, No delay, Write precomp)
061C   mov     a,#0F6H    |
061E   jnc     L0622      |
0620   mov     a,#0F6H    /
0622   -L0622:
0622   anl     p1,#0DCH   \ zapis polecenia do kontrolera
0624   movx    @r0,a      /
0625   anl     p1,#0DCH     bdzie zapis do DATA REGISTER kontrolera
0627   orl     p1,#003H
0629   clr     a          \ wyzerowanie timera
062A   mov     t,a        /
062B   jtf     L062D        wyzerowanie flagi przerwania od timera
062D   -L062D:
062D   mov     a,#044H		r4 oznacza bdzie liczb przepenie licznika w czasie 1 sek (68)
062F   xch     a,r4			wstawienie do A 'wypeniacza' pomidzy sektorami z r4
0630   strt    t			wczenie timera
0631   jmp     L0702		skok do czci zasadniczej

0633   -L0633:				WERYFIKACJA NA CIECE
0633   stop    tcnt		  \
0634   clr     a          | zatrzymanie timera i jego wyzerowanie
0635   mov     t,a        /
0636   mov     a,r3
0637   mov     r0,a			we do r0 z r3 LSB liczby bajtw w sektorze ($80 lub $00)
0638   mov     r4,#044H		liczba przepenie licznika w czasie 1 sek (68)
063A   anl     p1,#0DCH   \
063C   orl     p1,#001H   | zapis do TRACK REGISTER wartoci z r2
063E   mov     a,r2       |
063F   movx    @r0,a	  /
0640   anl     p1,#0DCH   \ przygotowanie do zapisu wartoci z (r1) do SECTOR REGISTER
0642   orl     p1,#002H   /
0644   mov     a,@r1		we do A numer biecego sektora z tablicy
0645   dec     r1			zmniejsz o 1 wskanik do numeru sektora w tablicy
0646   movx    @r0,a		zapisz numer sektora
0647   anl     p1,#0DCH   \
0649   mov     a,#088H    | zapis do COMMAND REGISTER komendy READ SECTOR (Sigle sector, Disable spin up, No delay)
064B   movx    @r0,a      /
064C   anl     p1,#0DCH   \ przygotowanie do odczytu z DATA REGISTER kontrolera
064E   orl     p1,#023H   /
0650   strt    t			uruchomienie licznika
0651   -L0651:
0651   jtf     L0672		przepenienie licznika -> zmniejszenie liczby przepenie
0653   -L0653:
0653   jnt1    L0651		jeeli nie byo Data Requestu -> ciasna ptla
0655   -L0655:
0655   movx    a,@r0		odczyt DATA REGISTER
0656   djnz    r0,L0653		odczytanie wszystkich bajtw sektora
0658   clr     a          \ wyzerowanie licznika
0659   mov     t,a        /
065A   jtf     L065C        wyzerowanie flagi przerwania od timera
065C   -L065C:
065C   jtf     L0678		przepenienie licznika -> Force Interrupt
065E   in      a,p1		  \	czy jest Interrupt Request?
065F   anl     a,#004H    /
0661   jz      L065C		nie -> ciasna ptla
0663   stop    tcnt			zatrzymanie licznika
0664   anl     p1,#0DCH   \
0666   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
0668   movx    a,@r0      /
0669   anl     a,#03CH	  \ jeeli wystpi bd DDM, RNF, CRC lub Lost Data -> Force Interrupt
066B   jnz     L0678      /
066D   mov     a,r1		  \ jeeli nie doszlimy do koca tablicy -> kontynuuj czytanie sektorw
066E   jb7     L0633	  /
0670   jmp     L067A		ok, nastpna cieka

0672   -L0672:
0672   jnt1    L0676		jeeli nie ma Data Requestu -> odczyt kolejnego bajtu
0674   jt1     L0655		jeeli by Data Requst -> odczyt DATA REGISTER
0676   -L0676:
0676   djnz    r4,L0653		zmniejszenie liczby przepenie o 1, kontynuacja ptli
0678   -L0678:
0678   jmp     L0562		Force Interrupt, bd

067A   -L067A:				FORMATUJ/WERYFIKUJ NASTPNE CIEKI
067A   in      a,p1		  \ jeeli ~SIDE=1 (druga strona) -> przeskok do L0690
067B   jb6     L0690      /
067D   inc     r2           zwikszenie numeru cieki w r2
067E   mov     a,r2       \ czy doszlimy do cieki 40?
067F   xrl     a,#028H    /
0681   jnz     L0694		nie -> formatuj nastpn ciek
0683   in      a,p2       \
0684   anl     a,#030H    | czy jest to format DSDD?
0686   xrl     a,#010H    /
0688   jnz     L0696		nie -> koniec weryfikacji
068A   orl     p1,#040H		ustawienie drugiej strony (~SIDE=1)
068C   mov     r0,#088H   \
068E   -L068E:            | ptla opniajca
068E   djnz    r0,L068E   /

0690   -L0690:				~SIDE=1 (druga strona)
0690   mov     a,r2         zaaduj do r2 numer cieki
0691   jz      L0696		jeeli zerowa -> koniec formatowania
0693   dec     r2			zmniejszenie numeru cieki
0694   -L0694:
0694   jmp     L0570		przeskok na pocztek ptli zapisujcej cieki

; Dojechalimy do ostatniej cieki

0696   -L0696:
0696   jf1     L069B		jeeli zakoczylimy faz weryfikacji -> przeskok (koniec formatowania)
0698   cpl     f1			F1 ustawiamy na 1 (faza weryfikacji)
0699   jmp     L0538		skok na pocztek ptli wykonujcej przejcie przez wszystkie cieki

; Koniec fazy weryfikacji

069B   -L069B:
069B   stop    tcnt			zatrzymanie licznika
069C   clr     f1			F1=0 (weryfikacja ok)
069D   orl     p2,#008H		omi rozpoznawanie gstoci na ciece 0 podczas odczytu/zapisu sektora
069F   -L069F:
069F   jmp     L06C0		udziel odpowiedzi na polecenie formatowania jeeli trzeba

; Udziel odpowiedzi po formatowaniu

06A1   -L06A1:
06A1   jz      L06B6		jeeli 256 bajtw w sektorze -> przeskok do oddzielnego fragmentu kodu
06A3   clr     a			domylnie do A kod bdu (0)
06A4   jf1     L06A7		bd -> przeskok
06A6   cpl     a			A=$FF (prawidowy status)
06A7   -L06A7:
06A7   mov     @r0,a		zapis do pierwszej komrki ($FF lub $00) status
06A8   -L06A8:
06A8   inc     r0
06A9   mov     @r0,a		do drugiej te
06AA   inc     r0
06AB   mov     @r0,#0FFH  \ do trzeciej $FF
06AD   inc     r0         /
06AE   mov     @r0,#0FFH	i do czwartej
06B0   dec     r0		  \
06B1   dec     r0         | cofnij wskanik, aby wskazywa na pierwsz wypenion komrk
06B2   dec     r0         /
06B3   clr     f0			bdziemy emitowa odpowied w normalu
06B4   jmp     L0300        skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff

; Sektory 256-bajtowe

06B6   -L06B6:
06B6   jf1     L06B9		jeeli bd formatowania -> przeskok
06B8   cpl     a			A=$FF (byo 0)
06B9   -L06B9:
06B9   mov     t,a			instrukcja bez znaczenia, zawarto rejestru t nie zostanie uyta
06BA   jmp     L06A8		udziel odpowiedzi tak jak dla sektorw 128-bajtowych, z tym, e pierwszym wyemitowanym bajtem bdzie 0 (zawarto r0)

06C0   -L06C0:				SPRAWD, CZY UDZIELI ODPOWIEDZI NA FORMATOWANIE
06C0   mov     r0,#077H	  \	we DAUX1
06C2   mov     a,@r0      /
06C3   xrl     a,#010H		czy jest on rwny $10?
06C5   jnz     L06D3		nie -> przeskok (bdzie odpowied)
06C7   -L06C7:
06C7   dec     r0		  \ odczyt DAUX2
06C8   mov     a,@r0      /
06C9   xrl     a,#050H		czy jest on rwny $50?
06CB   jnz     L06D3		nie -> przeskok (bdzie odpowied)
06CD   jf1     L06D1		skok do gwnej ptli stacji (F1 jest ustawione) -> brak odpowiedzi
06CF   jmp     L0516		skok na pocztek procedury formatujcej (powtrz formatowanie)

06D1   -L06D1:				NIE BDZIE ODPOWIEDZI PO FORMATOWANIU
06D1   jmp     L001C		skok do gwnej ptli

06D3   -L06D3:				BDZIE ODPOWIED PO FORMATOWANIU
06D3   mov     a,r3       \ przepisz do r0 z r3 LSB liczby bajtw w sektorze
06D4   mov     r0,a       /
06D5   jmp     L06A1		skok do fragmentu wysyajcego odpowied do komputera

; Zasadnicza procedura zapisujca zawarto cieki

0700   -L0700:
0700   jtf     L07CB		przekroczenie czasu -> bd
0702   -L0702:				ZAPIS CIEKI DYSKIETKI
0702   jnt1    L0700		jeeli nie ma Data Requesta -> ciasna ptla
0704   -L0704:
0704   movx    @r0,a		zapisz 1 bajt 'wypeniacza' midzy sektorami
0705   djnz    r0,L0702		zapisuj je w ptli

; Ostatni bajt 'wypeniacza'

0707   mov     t,a			instrukcja ta nie ma adnego znaczenia, rejestr t zostanie nadpisany pod 0771
0708   jtf     L070A        wyzerowanie flagi przerwania od timera
070A   -L070A:
070A   jt1     L0710		jeeli Data Request -> przeskok do zapisu
070C   -L070C:
070C   jtf     L07C9		przekroczenie czasu -> bd
070E   jnt1    L070C		jeeli nie ma Data Requesta -> ciasna ptla
0710   -L0710:
0710   movx    @r0,a		jeszcze jeden bajt 'wypeniacza'
0711   mov     r4,a			zapisanie do r4 'wypeniacza' midzy sektorami i bajtu po $F7

; Zapis 0 tyle razy, jaki by stan r5

0712   -L0712:
0712   mov     a,r5		  \ przepisz z r5 do r0 liczb zer, ktre zapisujemy
0713   mov     r0,a       /
0714   clr     a			bdziemy zapisywa 0
0715   jt1     L071B		jeeli Data Request -> przeskok dalej, aby zapisa bajt
0717   -L0717:
0717   jtf     L07C9		przekroczenie czasu -> bd
0719   -L0719:
0719   jnt1    L0717		jeeli nie ma Data Requesta -> ciasna ptla
071B   -L071B:
071B   movx    @r0,a		zapisz 0
071C   djnz    r0,L0719		ptla zapisujca 0 tyle razy, jaka bya warto r5
071E   in      a,p1		  \ jeeli Single Density kontrolera -> $L0733
071F   jb3     L0733      /

; 3 razy $F5

0721   mov     a,#0F5H		bajt do zapisu ($F5)
0723   jt1     L0729		jeeli Data Request -> przeskok dalej, aby zapisa bajt
0725   -L0725:
0725   jtf     L07C9		przekroczenie czasu -> bd
0727   jnt1    L0725		jeeli nie ma Data Requesta -> ciasna ptla
0729   -L0729:
0729   movx    @r0,a		zapis bajtu z A ($F5)
072A   mov     r0,#002H		jeszcze 2 razy bdziemy go zapisywa
072C   -L072C:
072C   jtf     L07C9		przekroczenie czasu -> bd
072E   -L072E:
072E   jnt1    L072C		jeeli nie ma Data Requesta -> ciasna ptla
0730   movx    @r0,a		ponowny zapis bajtu $F5
0731   djnz    r0,L072E		ptla zapisujca 2 razy bajt $F5. cznie bd 3.

; Zapis $FE (ID Address Mark)

0733   -L0733:
0733   mov     a,#0FEH		bajt to zapisu (ID Address Mark)
0735   jt1     L073B		jeeli Data Request -> przeskok dalej, aby zapisa bajt
0737   -L0737:
0737   jtf     L07C9		przekroczenie czasu -> bd
0739   jnt1    L0737		jeeli nie ma Data Requesta -> ciasna ptla
073B   -L073B:
073B   movx    @r0,a		zapis bajtu $FE

; Zapis numeru cieki z r2

073C   mov     a,r2			bdzie zapis wartoci z r2
073D   -L073D:
073D   jtf     L07C9		przekroczenie czasu -> bd
073F   jnt1    L073D		jeeli nie ma Data Requesta -> ciasna ptla
0741   movx    @r0,a		zapis wartoci z r2

; Zapis numeru strony dyskietki

0742   in      a,p1		  \
0743   rl      a          | przepisanie do bitu 0 w A wartoci sygnau ~SIDE
0744   rl      a          |
0745   anl     a,#001H    /
0747   -L0747:
0747   jtf     L07C9		przekroczenie czasu -> bd
0749   jnt1    L0747		jeeli nie ma Data Requesta -> ciasna ptla
074B   movx    @r0,a		zapis ~SIDE

; Zapis numeru sektora

074C   mov     a,@r1		we spod (r1) numer sektora z przygotowanej tablicy
074D   dec     r1			zmniejsz o 1 indeks tablicy
074E   -L074E:
074E   jtf     L07C9		przekroczenie czasu -> bd
0750   jnt1    L074E		jeeli nie ma Data Requesta -> ciasna ptla
0752   movx    @r0,a		zapisz numer sektora

; Zapis dugoci sektora

0753   in      a,p2			sprawdzenie, czy mamy gsto podwjn kontrolera
0754   jb5     L0757		nie -> przeskok (w r0 jest 0 z poprzedniej operacji)
0756   inc     r0			jeeli jest to gsto podwjna -> zwiksz r0 o 1 (256 bajtw na sektor)
0757   -L0757:
0757   mov     a,r0			zapis 0 (128 bajtw na sektor) lub 1 (256 bajtw na sektor)
0758   -L0758:
0758   jtf     L07C9		przekroczenie czasu -> bd
075A   jnt1    L0758		jeeli nie ma Data Requesta -> ciasna ptla
075C   movx    @r0,a		zapisz dugo sektora

; $F7 i zapis cigu bajtw o wartoci z r4

075D   mov     a,#0F7H		bajt do zapisu ($F7)
075F   -L075F:
075F   jtf     L07C9		przekroczenie czasu -> bd
0761   jnt1    L075F		jeeli nie ma Data Requesta -> ciasna ptla
0763   movx    @r0,a		zapisz bajt $F7
0764   mov     a,r6		  \ do r0 wpisujemy liczb obiegw ptli pobran z r6
0765   mov     r0,a       /
0766   mov     a,r4			bierzemy z r4 bajt do zapisu
0767   -L0767:
0767   jtf     L07C9		przekroczenie czasu -> bd
0769   -L0769:
0769   jnt1    L0767		jeeli nie ma Data Requesta -> ciasna ptla
076B   movx    @r0,a		zapisz bajt, ktry pobralimy z r4
076C   djnz    r0,L0769		zapisz w ptli bajty o wartoci, ktr pobralimy z r4

; Zapis 0 tyle razy, jaka bya warto r5

076E   mov     a,r5		  \ przepisz z r5 do r0 liczb zer, ktre zapiszemy
076F   mov     r0,a 	  /
0770   clr     a		  \ wyzerowanie licznika czasu
0771   mov     t,a        /
0772   -L0772:
0772   jtf     L07C9		przekroczenie czasu -> bd
0774   -L0774:
0774   jnt1    L0772		jeeli nie ma Data Requesta -> ciasna ptla
0776   movx    @r0,a		zapisz 0
0777   djnz    r0,L0774		zapisz w ptli 0 tyle razy, ile wynosi warto r5

0779   in      a,p1		  \ jeeli Single Density kontrolera -> L078E
077A   jb3     L078E	  /

; 3 razy $F5

077C   mov     a,#0F5H		bajt, ktry bdziemy zapisywa ($F5)
077E   jt1     L0784		jeeli Data Request -> przeskok dalej, do zapisu
0780   -L0780:
0780   jtf     L07C9		przekroczenie czasu -> bd
0782   jnt1    L0780		jeeli nie ma Data Requesta -> ciasna ptla
0784   -L0784:
0784   movx    @r0,a		zapis $F5
0785   mov     r0,#002H		jeszcze 2 razy bdziemy go zapisywa
0787   -L0787:
0787   jtf     L07C9		przekroczenie czasu -> bd
0789   -L0789:
0789   jnt1    L0787		jeeli nie ma Data Requesta -> ciasna ptla
078B   movx    @r0,a		ponowny zapis $F5
078C   djnz    r0,L0789		ptla zapisujca 2 razy $F5, cznie bdzie ich 3
078E   -L078E:

; $FB (Data Address Mark)

078E   mov     a,#0FBH		bdziemy zapisywa $FB (Data Address Mark)
0790   jt1     L0796		jeeli Data Request -> przeskok dalej, do zapisu
0792   -L0792:
0792   jtf     L07C9		przekroczenie czasu -> bd
0794   jnt1    L0792		jeeli nie ma Data Requesta -> ciasna ptla
0796   -L0796:
0796   movx    @r0,a		zapis $FB

; $FF tyle razy, jaki jest rozmiar sektora

0797   mov     a,r3		  \ z r3 pobieramy LSB liczby bajtw sektora i przenosimy j do r0
0798   mov     r0,a       /
0799   mov     a,#0FFH		sektor bdziemy zapisywa wartociami $FF
079B   -L079B:
079B   jtf     L07C9		przekroczenie czasu -> bd
079D   -L079D:
079D   jnt1    L079B		jeeli nie ma Data Requesta -> ciasna ptla
079F   movx    @r0,a	  \ zapis $FF tyle razy, jaki jest rozmiar sektora
07A0   djnz    r0,L079D   /

; F7 i cig bajtw o wartociach w w r4 o dugoci w r7

07A2   mov     a,#0F7H		bdziemy zapisywa $F7
07A4   -L07A4:
07A4   jtf     L07C9		przekroczenie czasu -> bd
07A6   jnt1    L07A4		jeeli nie ma Data Requesta -> ciasna ptla
07A8   movx    @r0,a		zapis $F7
07A9   mov     a,r7		  \ wpisz do r0 liczb zapisywanych bajtw z r7
07AA   mov     r0,a       /
07AB   mov     a,r4			bajt do zapisu z r4
07AC   -L07AC:
07AC   jtf     L07C9		przekroczenie czasu -> bd
07AE   -L07AE:
07AE   jnt1    L07AC		jeeli nie ma Data Requesta -> ciasna ptla
07B0   movx    @r0,a	  \	ptla zapisujca bajty z r4 tyle razy, jaka bya warto r7
07B1   djnz    r0,L07AE   /
07B3   mov     a,r1			przepisz do A z r1 indeks do tablicy wskazujcy na numer nastpnego sektora na ciece
07B4   jb7     L0712		jeeli nie wyszlimy poza tablice (s dalsze sektory) -> zapisuj nastpne

; Zapisalimy wszystkie sektory, teraz zapisujemy bajty wypenienia do Interrupt Requesta

07B6   mov     r0,#044H		tyle maksymalnie przepenie licznika moe wystpi
07B8   -L07B8:
07B8   mov     a,r4			bdzie wypenianie bajtami w r4
07B9   jnt1    L07BC		jeeli nie ma Data Requesta -> przeskok przez nadawanie bajtu
07BB   movx    @r0,a		zapisz bajt
07BC   -L07BC:
07BC   in      a,p1			sprawdzenie Interrupt Requesta kontrolera
07BD   jb2     L07E3		jest -> koniec cieki
07BF   mov     a,r4			bdziemy zapisywa bajt w r4
07C0   jnt1    L07C3		jeeli nie ma Data Requesta -> przeskok przez nadawanie bajtu
07C2   movx    @r0,a		zapisz bajt
07C3   -L07C3:
07C3   jtf     L07C7		przekroczenie czasu -> bd
07C5   jmp     L07B8		wypeniaj dalej

07C7   -L07C7:
07C7   djnz    r0,L07B8		zmniejsz o 1 liczb dopuszczalnych przepenie licznika
07C9   -L07C9:
07C9   jmp     L0562		zatrzymanie licznika, Force Interrupt i bd

07CB   -L07CB:
07CB   jnt1    L07CF		jeeli nie ma Data Requesta -> przeskok
07CD   jt1     L0704		jeeli Data Request -> przeskok do zapisywanie luki midzy sektorami
07CF   -L07CF:
07CF   djnz    r4,L0702		zmniejszenie o 1 liczby przepenie licznika, w cigu ktrych musi nastpi Data Request. czny czas czekania to 1 sek
07D1   in      a,p1		  \
07D2   cpl     a          | jeeli nie ma Interrupt Requesta -> Force Interrupt
07D3   jb2     L07E1      /
07D5   anl     p1,#0DCH   \
07D7   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
07D9   movx    a,@r0      /
07DA   cpl     a		  \ jeeli przyczyn Interrupt Requesta nie by Write Protect -> Force Interrupt
07DB   jb6     L07E1      /
07DD   mov     r0,#07BH     ustaw w wewntrznym statusie operacji kod oznaczajcy niepowodzenie spowodowane
07DF   mov     @r0,#00CH    zabezpieczeniem dyskietki przez zapisem
07E1   -L07E1:
07E1   jmp     L0562		zatrzymanie licznika, Force Interrupt i bd

; Wystpi Interrupt Request, koniec zapisywania cieki

07E3   -L07E3:
07E3   anl     p1,#0DCH   \
07E5   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
07E7   movx    a,@r0      /
07E8   anl     a,#044H		czy w bajcie statusu ustawione s bity LOST_DATA lub PROTECT?
07EA   jnz     L07E1		tak -> zatrzymanie licznika, Force Interrupt i bd
07EC   jmp     L067A		formatuj nastpne cieki

; Przy pomocy r0-r5 ustalenie numeru sektora na ciece w SECTOR REGISTER i numeru cieki w DATA REGISTER

07EE   -L07EE:
07EE   mov     a,r0		  \
07EF   mov     r0,#075H   |
07F1   mov     @r0,a	  |
07F2   dec     r0         |
07F3   mov     a,r1       |
07F4   mov     @r0,a      |
07F5   dec     r0         |
07F6   mov     a,r2       |
07F7   mov     @r0,a      |
07F8   dec     r0         | zapis w komrkach $70-$75 wartoci rejestrw r0-r5
07F9   mov     a,r3       |
07FA   mov     @r0,a      |
07FB   dec     r0         |
07FC   mov     a,r4       |
07FD   mov     @r0,a      |
07FE   dec     r0         |
07FF   mov     a,r5       |
0800   mov     @r0,a      /

0801   mov     r0,#077H	  \ pobranie DAUX1
0803   mov     a,@r0      /
0804   add     a,#0FFH	  \ r2 = 255 + DAUX1
0806   mov     r2,a       /
0807   dec     r0         \ pobranie DAUX2
0808   mov     a,@r0      /
0809   addc    a,#0FFH    \ r3 = 255 + DAUX2 + carry - do DAUX1-2 dodajemy $FFFF, czyli w wyniku otrzymujemy w r2,r3 numer sektora od 0 a nie od 1
080B   mov     r3,a       /
080C   mov     r1,#0EEH		(255-18) - liczba sektorw w SD i DD
080E   mov     r4,#030H		LSB(65536 - 720)
0810   mov     r5,#0FDH		MSB(65536 - 720). 720 to liczba sektorw w SD i DD
0812   in      a,p2		  \ jeeli SD albo ED -> przeskok
0813   jb5     L0817      /
0815   jmp     L0022		(skok do $822) - liczba sektorw ustawiona

0817   -L0817:
0817   in      a,p1		  \ sprawd, czy ustawiona jest gsto podwjna kontrolera
0818   anl     a,#008H    /
081A   jnz     L0822		nie (gsto SD) -> $822 - liczba sektorw ustawiona
081C   mov     r1,#0E6H		(256 - 26) liczba sektorw w ED
081E   mov     r4,#0F0H		LSB(65536 - 1040)
0820   mov     r5,#0FBH		MSB(65536 - 1040). 1040 to liczba sektorw w ED
0822   -L0822:
0822   mov     a,r2       \
0823   add     a,r4       |
0824   mov     r0,a       | dodaj numer sektora od 0 do ujemnej cznej liczby sektorw otrzymujc wynik w r0 i A (r0, A - nr_sekt - 1 - liczba_sekt)
0825   mov     a,r3       |
0826   addc    a,r5       /
0827   jnc     L0840		jeeli nr sektora jest mniejszy od cznej liczby sektorw -> oblicz numer sektora i cieki
0829   xch     a,r0			w r0,A powstaa liczba dodatnia, jest to 'nadwyka' sektorw ponad pierwsz stron
082A   add     a,r4			dodajemy do niej ujemn liczb sektorw w r4,r5
082B   cpl     a			odwracamy LSB wyniku znajdujcy si w A otrzymujc liczb dodatni. Sektory na drugiej stronie numerowane s od tyu
082C   mov     r2,a			dodatnie LSB do r2
082D   mov     a,r0			to samo robimy z MSB
082E   addc    a,r5			dodajemy MSB do ujemnej liczby sektorw
082F   cpl     a			odwracamy
0830   mov     r3,a			wynik do r3. Czyli obliczylimy numer sektora w r2 i r3 dla drugiej strony.
0831   jc      L085D		jeeli jednak po raz drugi przekroczylimy czn liczb sektorw -> zy DAUX (C=1, co oznacza bd)
0833   in      a,p2		  \ sprawdzenie ustawionego wewntrznie formatu
0834   anl     a,#030H    /
0836   xrl     a,#010H		czy DSDD?
0838   clr     c		  \ C=1 oznacza, e DAUX nie by ok
0839   cpl     c          /
083A   jnz     L085D		nie DSDD -> zy DAUX
083C   orl     p1,#040H		ustawienie SIDE=1 - druga strona
083E   jmp     L0042		kontynuacja (przeliczenie numeru sektora na numer sektora na ciece i numer cieki)

; Przeliczenie numeru sektora na numer sektora na ciece i numer cieki

0840   -L0840:
0840   anl     p1,#0BFH		ustawienie SIDE=0 (pierwsza strona)
0842   mov     r0,#0FFH		domylny nr cieki = -1
0844   mov     a,r2			A = LSB (nr sektora od 0)
0845   inc     r3			po wykonaniu: r3 = MSB(nr sektora) + 1. Jest to potrzebne dla djnz
0846   -L0846:
0846   inc     r0			zwiksz nr cieki o 1
0847   add     a,r1			A += - liczba sektorw na ciek, czyli od cznej liczby sektrw odejmujemy liczb sektorw na ciece
0848   jc      L0846		nie nastpio przeniesienie do starszego bajtu
084A   djnz    r3,L0846		nastpio przeniesienie, wic zmniejszamy o 1 starszy bajt
084C   xch     a,r1			przepisujemy czn ujemn liczb sektorw na ciece do A a obliczony ujemny nr sektora na ciece do r1
084D   cpl     a		  \ po zanegowaniu i dodaniu 1 otrzymujemy dodatni liczb sektorw na ciece w A
084E   inc     a		  /
084F   add     a,r1			dodajemy t liczb do r1, w ktrym mamy ujemny nr sektora na ciece, gdy pod koniec odjlimy jeden raz za duo
0850   inc     a			w wyniku otrzymujemy nr sektora numerowany od 1
0851   anl     p1,#0DCH   \
0853   orl     p1,#002H   | zapisz do SECTOR REGISTER warto w A
0855   movx    @r0,a      /
0856   anl     p1,#0DCH   \
0858   orl     p1,#003H   | bdzie zapis do DATA REGISTER kontrolera
085A   mov     a,r0       | zapis do nr cieki wartoci z r0
085B   movx    @r0,a      /
085C   clr     c			C=0, DAUX ok (obliczony jest nr cieki i sektora na ciece)
085D   -L085D:
085D   mov     r0,#070H   \
085F   mov     a,@r0      |
0860   mov     r5,a       |
0861   inc     r0         |
0862   mov     a,@r0      |
0863   mov     r4,a       |
0864   inc     r0         |
0865   mov     a,@r0      |
0866   mov     r3,a       |
0867   inc     r0         |
0868   mov     a,@r0      | odczyt z komrek $70-$75 rejestrw r0-r5 i psw
0869   mov     r2,a       |
086A   inc     r0         |
086B   mov     a,@r0      |
086C   mov     r1,a       |
086D   inc     r0         |
086E   mov     a,@r0      |
086F   mov     r0,a       |
0870   mov     a,psw      /
0871   jb0     L0879		jeeli ustawiony jest najmodszy bit -> powrt do 091A poprzez 0879
0873   jb1     L0877		jeeli b0=0 i b1=1 -> powrt do 0AC9 poprzez 0877
0875   jmp     L011A		skok do 091A - powrt do wywoujcej procedury
0877   -L0877:
0877   jmp     L02C9		skok do 0AC9 - powrt do wywoujcej procedury
0879   -L0879:
0879   jmp     L011A		skok do 091A - powrt do wywoujcej procedury

; Procedura odczytu i zapisu z i bez weryfikacji

0900   in      a,p1		  \
0901   anl     a,#010H    | jeeli Master Reset jest wyczony -> przeskok
0903   jnz     L0914      /
0905   orl     p1,#010H		wyczenie Master Reset kontrolera
0907   mov     r6,#088H   \
0909   -L0909:            | ptla opniajca
0909   djnz    r6,L0909   /
090B   anl     p1,#0DCH   \
090D   mov     a,#0D0H    | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
090F   movx    @r0,a      /
0910   mov     r6,#035H   \
0912   -L0912:            | ptla opniajca
0912   djnz    r6,L0912   /
0914   -L0914:
0914   mov     a,psw	  \
0915   anl     a,#0FCH    | wyzerowanie bitw SP0 i SP1, aby powrt po L07EE nastpi do 091A
0917   mov     psw,a      /
0918   jmp     L07EE		przy pomocy r0-r5 ustalenie numeru sektora na ciece w SECTOR REGISTER i numeru cieki w DATA REGISTER

091A   jnc     L093E		jeeli C=0 (DAUX ok) -> parametry ok
091C   in      a,p2		  \ jeeli ustawiony jest bit 1 w p2 (zapis lub zapis z weryfikacj -> nie rozpoznano polecenia
091D   jb1     L093B      /
091F   cpl     a		  \ jeeli jest DD lub DSDD -> nie rozpoznano polecenia
0920   jb5     L093B      /
0922   in      a,p1		  \ sprawdzenie ustawionej gstoci kontrolera
0923   anl     a,#008H    /
0925   jz      L093B		jeeli Double Density -> nie rozpoznano polecenia
0927   anl     p1,#0F7H		ustawienie Double Density kontrolera
0929   orl     p2,#030H		ustawienie gstoci ED, w ktrej jest wicej sektorw
092B   mov     a,psw      \
092C   anl     a,#0FCH    | ustawienie bitu SP0 w psw, powrt z 07EE nastpi do 091A
092E   orl     a,#001H    |
0930   mov     psw,a      /
0931   jmp     L07EE		przy pomocy r0-r5 ustalenie numeru sektora na ciece w SECTOR REGISTER i numeru cieki w DATA REGISTER

; Nie uywany fragment

0933   jnc     L093E		jeeli C=0 (DAUX ok) -> parametry ok
0935   orl     p1,#008H		wyczenie Double Denstity kontrolera
0937   anl     p2,#0CFH   \ ustaw gsto na Single Density
0939   orl     p2,#020H   /

; Skok w to miejsce odbywa si wtedy, gdy numer sektora podany w DAUX nie pasuje do adnej gstoci

093B   -L093B:
093B   sel     mb0        \ nie rozpoznano polecenia, powrt
093C   jmp     L00B4      /

; DAUX ok (zawierajcy numer sektora podlegajcego operacji)

093E   -L093E:
093E   sel     mb0			pierwszy bank pamici
093F   call    L0200        przetransmituj kod przyjcia polecenia ('A')
0941   sel     mb1			drugi bank pamici
0942   in      a,p2       \
0943   anl     a,#007H    | sprawdzenie, czy 3 najmodsze bity w p2 s rwne 001 (odczyt)
0945   xrl     a,#001H    /
0947   jz      L0986		jest 001 (odczyt) -> zasadnicza cz odczytu lub zapisu
0949   mov     r0,#07FH		bdzie domylnie zapis 128 bajtw danych sektora
094B   mov     a,psw      \
094C   orl     a,#001H    | ustawiamy b0 psw, aby zaznaczy, e nie przesyamy sektorw 1-3 w DD ani DSDD
094E   mov     psw,a      /
094F   in      a,p2       \ jeeli gsto SD lub ED -> odczyt z Data Out (liczba bajtw ju ustawiona)
0950   jb5     L096F      /
0952   in      a,p1		  \ sprawdzenie SIDE
0953   anl     a,#040H    /
0955   jnz     L096D		jeeli SIDE=1 (druga strona) -> bdzie zapis 256 bajtw
0957   anl     p1,#0DCH   \
0959   orl     p1,#023H   | odczytaj DATA REGISTER kontrolera do A (nr cieki)
095B   movx    a,@r0      /
095C   jnz     L096D		jeeli niezerowy -> na pewno bdzie zapis 256 bajtw
095E   anl     p1,#0DCH   \
0960   orl     p1,#022H   | odczytaj warto z SECTOR REGISTER do A
0962   movx    a,@r0      /
0963   add     a,#0FCH		sprawdzamy, czy numer sektora podlegajcego operacji jest z zakresu 1-3
0965   jc      L096D		nie -> bdziemy odczytywa 256 bajtw z Data Out
0967   mov     a,psw      \
0968   anl     a,#0FEH    | kasujemy b0 psw, aby zaznaczy, e przesyamy sektory 1-3 w DD lub DSDD
096A   mov     psw,a      /
096B   jmp     L016F		(096F) - odczyt z Data Out

096D   -L096D:
096D   mov     r0,#0FFH		bdzie odczyt 256 bajtw danych sektora
096F   -L096F:
096F   sel     mb0	      \ odczytaj z Data Out okrelon liczb bajtw
0970   jmp     L0225      /

0972   mov     a,psw	  \ (powrt z 0225) jeeli nie s to sektory 1-3 w DD lub DSDD -> zasadniczy odczyt/zapis
0973   jb0     L0986      /
0975   mov     r0,#080H		pod tym adresem bdziemy zapisywa
0977   mov     a,t			wzicie ostatnio przeczytanego bajtu przed sum kontroln do A
0978   mov     @r0,a		zapis pod adresem $80
0979   dec     r0			$7F
097A   -L097A:				przepisz bajty [$01-$7F] -> [$81-$FF]
097A   mov     a,@r0		we warto z komrki biecej
097B   xch     a,r0		  \
097C   orl     a,#080H    | na adresie w r0 ustaw najstarszy bit
097E   xch     a,r0       /
097F   mov     @r0,a		przepisz pod ten adres odczytan warto
0980   xch     a,r0       \
0981   anl     a,#07FH    | na adresie w r0 wykasuj najmodszy bit
0983   xch     a,r0       /
0984   djnz    r0,L097A		ptl si, a przepiszesz wszystkie bajty
0986   -L0986:				ZASADNICZA CZʌ ODCZYTU/ZAPISU
0986   clr     f1			status ok
0987   in      a,p2		  \ sprawdzenie bitu b3 p2, ktry okrela czy wykona przesunicie gowicy na ciek 0 w celu zrobienia przerwy w odczycie
0988   anl     a,#008H	  /
098A   jz      L098E		tak -> id na ciek 0
098C   jmp     L0300        (0B00) przesu gowic na odpowiedni ciek i wykonaj odczyt lub zapis

098E   -L098E:				PRZESU GOWIC NA CIEK 0 I WYKONAJ PRZERW
098E   anl     p1,#0DCH   \
0990   orl     p1,#023H   | odczytaj DATA REGISTER kontrolera do A (numer danej cieki)
0992   movx    a,@r0      / 0992 - ODCZYT Z TRACK REGISTER LUB DATA REGISTER
0993   mov     r0,a			do r0
0994   mov     a,psw      \
0995   xrl     a,r0       |
0996   anl     a,#0F8H    | przepisanie trzech najmodszych bitw numeru cieki jako trzech najmodszych bitw psw. Reszta psw jest niezmieniona
0998   xrl     a,r0       |
0999   mov     psw,a      /
099A   mov     a,r0       \
099B   rl      a          | przepisz do r0 numer cieki * 4 (tak, aby zaczyna si od najstarszego bitu)
099C   rl      a          |
099D   mov     r0,a       /
099E   anl     p1,#0DCH   \
09A0   orl     p1,#022H   | odczyt wartoci z SECTOR REGISTER kontrolera
09A2   movx    a,@r0      /
09A3   xrl     a,#0F7H	    czy numer sektora ma sztuczn warto $F7?
09A5   jz      L09A9	   	tak -> przeskok (w A bdzie 0)
09A7   xrl     a,#0F7H		nie -> odwrcenie dziaania poprzedniego xrl
09A9   -L09A9:
09A9   xrl     a,r0       \
09AA   anl     a,#01FH    | wpisanie do A wartoci <3 najstarsze bity nr cieki><nr sektora>
09AC   xrl     a,r0       /
09AD   anl     p2,#0F7H		przy odczycie/zapisie przesu gowic na ciek 0 i rozpoznaj gsto
09AF   anl     p1,#0EFH     Master Reset kontrolera = 0
09B1   mov     r0,#088H   \
09B3   -L09B3:            | ptla opniajca
09B3   djnz    r0,L09B3   /
09B5   orl     p1,#010H     Master Reset Kontrolera = 1
09B7   mov     r0,#088H   \
09B9   -L09B9:            | ptla opniajca
09B9   djnz    r0,L09B9   /
09BB   mov     r0,a			obliczony numer sektora z numerem cieki do r0
09BC   mov     a,#0D0H    \ przesanie Force Interrupt do kontrolera
09BE   movx    @r0,a      /
09BF   mov     a,r0			obliczony numer sektora z numerem cieki do r0
09C0   mov     r0,#035H   \
09C2   -L09C2:            | ptla opniajca
09C2   djnz    r0,L09C2   /
09C4   mov     r0,a			obliczony numer sektora z bitami numeru cieki do r0
09C5   anl     a,#01FH	  \ jeeli 5 najmodszych bitw numeru sektora nie ma wartoci 0 -> przeskok
09C7   jnz     L09CB      /
09C9   mov     a,#0F7H		jeeli natomiast bya tam warto 0, wwczas przyjmij $F7 jako numer sektora ze ciek (by moe, aby SECTOR REGISTER by <> 0)
09CB   -L09CB:
09CB   anl     p1,#0DCH   \
09CD   orl     p1,#002H   | zapis do SECTOR REGISTER wartoci w A
09CF   movx    @r0,a      / (ponisze RESTORE zamazuje TRACK REGISTER, std numer cieki jest wczeniej zapamitywany)
09D0   mov     a,#008H    \
09D2   anl     p1,#0DCH   | zapis do COMMAND REGISTER komendy RESTORE (Disable spin-up, No verify, 6ms)
09D4   movx    @r0,a      /
09D5   mov     a,t			ostatnio przeczytany bajt przed sum kontroln do A
09D6   xch     a,r0			numer cieki wraz z sektorem przepisujemy do A, ostatnio przeczytany bajt do r0
09D7   rr      a		  \
09D8   rr      a          |
09D9   rr      a          | po przesuniciu bitw numeru ciezki i sektora w prawo o 5 pozycji i wyodrbnieniu 3 najmodszych bitw otrzymujemy
09DA   rr      a          |	3 najstarsze bity numeru cieki (wpisane jako bity b0-b2 w A)
09DB   rr      a          |
09DC   anl     a,#007H    /
09DE   jmp     L0200        skok do 0A00

0A00   -L0A00:				3 najstarsze bity numeru cieki s trzema najmodszymi w A. Reszta bitw w A zawiera licznik ptli (pocztkowo rwny 0)
0A00   mov     t,a			zainicjuj tym t. Jest to warto inna za kadym obiegiem ptli
0A01   strt    t			wczenie licznika. 3 najstarsze bity numeru cieki sa wci w A
0A02   jtf     L0A06		pierwsze przepenienie -> przeskok
0A04   jmp     L0202		(0A02) ciasna ptla, oczekuj na przepenienie

0A06   -L0A06:
0A06   jtf     L0A0A		drugie przepenienie -> przeskok
0A08   jmp     L0206 		(0A06) ciasna ptla, oczekuj na przepenienie

; Czas przepenienia licznika to 1/67.7 sek. My czekamy przez ok. 6.5 przepenie licznika w jednym obiegu ptli a obiegw jest 2^5. Zatem cznie czekamy
; przez 6.5*32/67.7 = ok. 3 sek.!!

0A0A   -L0A0A:
0A0A   jtf     L0A0E		trzecie przepenienie -> przeskok
0A0C   jmp     L020A		(0A0A) ciasna ptla, oczekuj na przepenienie

0A0E   -L0A0E:
0A0E   jtf     L0A12		czwarte przepenienie -> przeskok
0A10   jmp     L020E		(0A0E) ciasna ptla, oczekuj na przepenienie

0A12   -L0A12:
0A12   jtf     L0A16		pite przepenienie -> przeskok
0A14   jmp     L0212		(0A12) ciasna ptla, oczekuj na przepenienie

0A16   -L0A16:
0A16   jtf     L0A1A		szste przepenienie -> przeskok
0A18   jmp     L0216		(0A16) ciasna ptla, oczekuj na przepenienie

0A1A   -L0A1A:
0A1A   jtf     L0A1E		sidme przepenienie -> przeskok
0A1C   jmp     L021A		(0A1A) ciasna ptla, oczekuj na przepenienie

0A1E   -L0A1E:
0A1E   stop    tcnt			zatrzymanie licznika
0A1F   mov     t,a			3 najstarsze bity numeru cieki przepisujemy do t na przechowanie (+licznik na 5 najstarszych bitach)
0A20   in      a,p1		  \ jeeli Interrupt Request -> wykonaj polecenie READ ADDRESS
0A21   jb2     L0A44      /
0A23   mov     a,t			3 najstarsze bitu numeru cieki przepisujemy do A (reszta to licznik)
0A24   add     a,#008H		zwikszenie licznika na pozostaych bitach w A
0A26   jnc     L0A00		nie ma przepenienia -> kontynuuj czekanie. Po wyjciu 5 najstarszych bitw w A bdzie zerami
0A28   rl      a          \
0A29   rl      a          | przechowywane w A starsze bity numeru cieki przesuwamy o 3 pozycje w lewo, aby zrobi miejsce dla modszych, ktre mamy w psw
0A2A   rl      a          | 3 najmodsze bity zostaj wyzerowane
0A2B   anl     a,#038H    /
0A2D   xch     a,r0		  \ numer cieki bez 3 najmodszych bitw z A do r0. Ostatnio przeczytany bajt z r0 do t.
0A2E   mov     t,a        /
0A2F   mov     a,#0D0H    \
0A31   anl     p1,#0DCH   | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
0A33   movx    @r0,a      /
0A34   mov     a,psw      \
0A35   xrl     a,r0       | utworzenie w A numeru cieki. 3 najmodsze bity tego numeru bd pochodzi z psw, reszta z r0
0A36   anl     a,#007H    |
0A38   xrl     a,r0       /
0A39   mov     r0,#035H   \
0A3B   -L0A3B:            | ptla opniajca
0A3B   djnz    r0,L0A3B   /
0A3D   anl     p1,#0DCH   \
0A3F   orl     p1,#001H   | zapis do TRACK REGISTER kontrolera wartoci z A
0A41   movx    @r0,a      /
0A42   jmp     L04CC		(0CCC) - jeeli to pierwsza poraka to powtrka, w przeciwnym wypadku koniec

0A44   -L0A44:				JESTEMY NA CIECE 0, by Interrupt Request
0A44   anl     p1,#0DCH   \
0A46   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera, wynik jednak nie zostanie uyty
0A48   movx    a,@r0      /
0A49   in      a,p2		  \ jeeli jest to zapis lub zapis z weryfikacj -> przygotuj nr cieki, przesu gowic i wykonaj operacj
0A4A   jb1     L0ACF      /
0A4C   cpl     a          \ jeeli wewntrzna gsto ustawiona jest na DD lub DSDD -> przygotuj nr cieki, przesu gowic i wykonaj operacj
0A4D   jb5     L0ACF      /
0A4F   anl     p1,#0F7H     ustawienie ~DDEN (Double Density Enable) na 0
0A51   orl     p2,#030H		prba rozpoznania gstoci. Najpierw ustaw ED, wykonaj READ ADDRESS i jeeli si nie uda to ustawimy SD.
0A53   mov     a,r0			ostatnio przeczytany bajt z r0 do A
0A54   mov     r0,#088H   \
0A56   -L0A56:            | ptla opniajca
0A56   djnz    r0,L0A56   /
0A58   mov     r0,a			zostanie przeczytany bajt z A do r0
0A59   mov     a,#0CCH    \
0A5B   anl     p1,#0DCH   | zapis do COMMAND REGISTER komendy READ ADDRESS (Disable spin-up, 30ms delay)
0A5D   movx    @r0,a      /
0A5E   clr     a          \ wyzerowanie timera
0A5F   mov     t,a        /
0A60   mov     a,#011H		tyle przepenie moe maksymalnie wystpi podczas czytania (ok 0.2 sek)
0A62   jtf     L0A64		wykasowanie flagi przepenienia od timera
0A64   -L0A64:
0A64   strt    t			uruchom licznik
0A65   anl     p1,#0DCH   \ bdzie odczyt z DATA REGISTER kontrolera do A
0A67   orl     p1,#023H   /
0A69   -L0A69:
0A69   jtf     L0A9E		przekroczenie czasu -> bd
0A6B   -L0A6B:
0A6B   jnt1    L0A69		jeeli nie byo Data Request -> ciasna ptla
0A6D   -L0A6D:
0A6D   movx    a,@r0		odczyt TRACK ADDR
0A6E   clr     a          \
0A6F   mov     t,a        / wyzerowanie timera
0A70   jtf     L0A72		wykasowanie flagi przepenienia od timera
0A72   -L0A72:
0A72   jt1     L0A78		jeeli jest Data Request -> przeskok do odczytu
0A74   -L0A74:
0A74   jtf     L0AA9		przekroczenie czasu -> bd
0A76   jnt1    L0A74		jeeli nie byo Data Requesta -> ciasna ptla
0A78   -L0A78:
0A78   movx    a,@r0		odczyt SIDE NUMBER
0A79   -L0A79:
0A79   jtf     L0AA9		przekroczenie czasu -> bd
0A7B   jnt1    L0A79		jeeli nie byo Data Requesta -> ciasna ptla
0A7D   movx    a,@r0		odczyt SECTOR ADDR
0A7E   -L0A7E:
0A7E   jtf     L0AA9		przekroczenie czasu -> bd
0A80   jnt1    L0A7E		jeeli nie byo Data Requesta -> ciasna ptla
0A82   movx    a,@r0		odczyt SECTOR LENGTH
0A83   -L0A83:
0A83   jtf     L0AA9		przekroczenie czasu -> bd
0A85   jnt1    L0A83		jeeli nie byo Data Requesta -> ciasna ptla
0A87   movx    a,@r0		odczyt CRC1
0A88   -L0A88:
0A88   jtf     L0AA9		przekroczenie czasu -> bd
0A8A   jnt1    L0A88		jeeli nie byo Data Requesta -> ciasna ptla
0A8C   movx    a,@r0		odczyt CRC2
0A8D   -L0A8D:
0A8D   jtf     L0AA9		przekroczenie czasu -> bd
0A8F   in      a,p1		  \
0A90   cpl     a          | jeeli nie ma Interrupt Requesta -> ciasna ptla
0A91   jb2     L0A8D      /
0A93   anl     p1,#0DCH   \
0A95   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
0A97   movx    a,@r0      /
0A98   anl     a,#01CH		czy RNF, CRC lub LOST DATA?
0A9A   jnz     L0AA9		tak -> bd
0A9C   jmp     L02BE		(0ABE) - by Interrupt Request, bez bdu

; Przekroczenie czasu przed oczytaniem pierwszego bajtu podczas rozpoznawania gstoci

0A9E   -L0A9E:
0A9E   jnt1    L0AA2		jeeli nie ma Data Requesta -> zmniejsz nr przepenienia
0AA0   jt1     L0A6D		jeeli jest Data Request -> zacznij czyta dane od kontrolera
0AA2   -L0AA2:
0AA2   dec     a			zmniejsz o 1 numer przepenienia
0AA3   jnt1    L0AA7		jeeli nie ma Data Requesta -> przeskok
0AA5   jt1     L0A6D		jeeli jest Data Request -> zacznij czyta
0AA7   -L0AA7:
0AA7   jnz     L0A6B		jeeli licznik przepenie nie osign 0 -> kontynuuj czekanie
0AA9   -L0AA9:
0AA9   mov     a,#0D0H    \
0AAB   anl     p1,#0DCH   | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt) - nieudane rozpoznanie gstoci
0AAD   movx    @r0,a      /
0AAE   mov     a,r0			ostatnio przeczytany bajt z r0 do A
0AAF   mov     r0,#035H   \
0AB1   -L0AB1:            | ptla opniajca
0AB1   djnz    r0,L0AB1   /
0AB3   orl     p1,#008H		wyczenie Double Density kontrolera
0AB5   anl     p2,#0CFH   \ ustaw gsto na Single Density
0AB7   orl     p2,#020H   /
0AB9   mov     r0,#088H   \
0ABB   -L0ABB:            | ptla opniajca
0ABB   djnz    r0,L0ABB   /
0ABD   mov     r0,a			ostatnio przeczytany bajt z A do r0

; Interrupt Request bez bdu

0ABE   stop    tcnt			zatrzymanie licznika
0ABF   mov     a,r0       \ ostatnio przeczytany bajt z r0 do t
0AC0   mov     t,a        /
0AC1   mov     a,psw	  \
0AC2   anl     a,#0FCH    | ustawienie w psw bitu 1, aby powrt po 07EE nastpi pod 0AC9
0AC4   orl     a,#002H    |
0AC6   mov     psw,a      /
0AC7   jmp     L07EE		obliczenie numeru sektora i numeru cieli w SECTOR REGISTER i DATA REGISTER na podstawie DAUX

; Powrt po 07EE

0AC9   jnc     L0AE1		jeeli C=0 (DAUX ok) -> przeskok do miejsca, gdzie ustawia si gowic
0ACB   clr     f1	      \ F1=1 (niepowodzenie)
0ACC   cpl     f1         /
0ACD   jmp     L04CC		zakoczenie obsugi polecenia odczytu bdem

; DD lub DSDD lub zapis sektora

0ACF   -L0ACF:
0ACF   mov     a,t			3 najstarsze bitu numeru cieki przepisujemy do A
0AD0   rl      a          \
0AD1   rl      a          | przesuwamy je o 3 pozycje w lewo, aby zrobi miejsce dla modszych bitw, ktre mamy w psw
0AD2   rl      a          /
0AD3   anl     a,#038H		maska wyodrbniajca tylko starsze bity
0AD5   xch     a,r0			bajt ze starszymi bitami do r0
0AD6   mov     t,a			ostatnio przeczytany bajt z r0 do t
0AD7   mov     a,psw	  \
0AD8   xrl     a,r0       | wyodrbnij z psw zapisane wczeniej 3 najmodsze bity numeru cieki
0AD9   anl     a,#007H    /
0ADB   xrl     a,r0			pocz je ze starszymi bitami w r0
0ADC   anl     p1,#0DCH   \
0ADE   orl     p1,#003H   | zapis do DATA REGISTER kontrolera wartoci z A
0AE0   movx    @r0,a      / (numeru cieki, na ktr ma przesun si gowica)
0AE1   -L0AE1:
0AE1   clr     a			A=0, bo znajdujemy si na ciece 0
0AE2   anl     p1,#0DCH   \
0AE4   orl     p1,#001H   | zapisz A do TRACK REGISTER kontrolera (SEEK przepisuje zawarto DATA REGISTER do TRACK REGISTER)
0AE6   movx    @r0,a      /
0AE7   jmp     L0300        (0B00) - przesu gowic na odpowiedni ciek i wykonaj odczyt albo zapis

0B00   anl     p1,#0DCH   \
0B02   orl     p1,#021H   | odczytaj warto z TRACK REGISTER do A
0B04   movx    a,@r0      /
0B05   mov     r0,a			do r0
0B06   anl     p1,#0DCH   \
0B08   orl     p1,#023H   | odczytaj warto z DATA REGISTER do A
0B0A   movx    a,@r0      /
0B0B   xrl     a,r0			czy obecna cieka i dana s takie same?
0B0C   jnz     L0B12		nie -> wykonaj SEEK
0B0E   mov     a,t		  \ przepisanie ostatnio przeczytanego bajtu przed sum kontroln z t do r0
0B0F   mov     r0,a       /
0B10   jmp     L0373		(0B73) - wykonaj prby odczytu lub zapisu sektora

0B12   -L0B12:
0B12   anl     p2,#0F7H		przy odczycie/zapisie przesu gowic na ciek 0 i rozpoznaj gsto
0B14   mov     a,#018H    \
0B16   anl     p1,#0DCH   | zapis do COMMAND REGISTER komendy SEEK (Enable Spin-up, No Verify, 6ms)
0B18   movx    @r0,a      /
0B19   mov     a,t	      \ przepisanie ostatnio przeczytanego bajtu przed sum kontroln z t do r0
0B1A   mov     r0,a       /
0B1B   clr     a          \ wyzerowanie timera
0B1C   mov     t,a        /
0B1D   mov     a,psw		w A przygotowujemy now warto psw
0B1E   anl     a,#03FH		wykasowanie obu znacznikw przeniesienia
0B20   orl     a,#007H		ustawienie na 3 najmodszych bitach i 3 najstarszych bitach licznika ptli
0B22   strt    t			uruchom licznik, bdziemy czeka na jego 6 przepenie (ok 9 ms)
0B23   -L0B23:
0B23   mov     psw,a		zapisanie do psw przygotowanej wartoci w A

; Czas wykonania caej ptli = 2^5 (5 bitw w psw) * 6 przepenie / 67.8 = 2.83 sek

0B24   jtf     L0B2B		jeeli 1-sze przepenienie -> dalej
0B26   in      a,p1		  \ jeeli Interrupt Request -> 0B6E
0B27   jb2     L0B6E      /
0B29   jmp     L0324		(0B24) - ciasna ptla

0B2B   -L0B2B:
0B2B   jtf     L0B32		jeeli 2-gie przepenienie -> dalej
0B2D   in      a,p1		  \ jeeli Interrupt Request -> 0B6E
0B2E   jb2     L0B6E	  /
0B30   jmp     L032B		(0B2B) - ciasna ptla

0B32   -L0B32:
0B32   jtf     L0B39		jeeli 3-cie przepenienie -> dalej
0B34   in      a,p1		  \ jeeli Interrupt Request -> 0B6E
0B35   jb2     L0B6E	  /
0B37   jmp     L0332		(0B32) - ciasna ptla

0B39   -L0B39:
0B39   jtf     L0B40		jeeli 4-te przepenienie -> dalej
0B3B   in      a,p1		  \ jeeli Interrupt Request -> 0B6E
0B3C   jb2     L0B6E	  /
0B3E   jmp     L0339		(0B39) - ciasna ptla

0B40   -L0B40:
0B40   jtf     L0B47	  	jeeli 5-te przepenienie -> dalej
0B42   in      a,p1		  \ jeeli Interrupt Request -> 0B6E
0B43   jb2     L0B6E	  /
0B45   jmp     L0340		(0B40) - ciasna ptla

0B47   -L0B47:
0B47   jtf     L0B4E		jeeli 6-te przepenienie -> dalej
0B49   in      a,p1		  \ jeeli Interrupt Request -> 0B6E
0B4A   jb2     L0B6E	  /
0B4C   jmp     L0347		(0B47) - ciasna ptla

0B4E   -L0B4E:
0B4E   mov     a,psw		psw do A, na jego 3 najmodszych bitach i 2 najstarszych jest licznik ptli
0B4F   dec     a			zmniejszenie licznika ptli
0B50   jb3     L0B23		jeeli nie nastpia poyczka z bitu 3 -> czekaj dalej w ptli
0B52   add     a,#048H	   	przywrcenie na 3 namodszych bitach stanu takiego jak na pocztku, dodanie 1 do wartoci na 2 najstarszych bitach
0B54   jnc     L0B23       	jeeli nie ma przepenienia -> kontynuacja ptli
0B56   stop    tcnt			zatrzymanie licznika
0B57   mov     a,r0		  \ ostatnio przeczytany bajt przed sum kontroln z r0 do t
0B58   mov     t,a        /
0B59   mov     a,#0D0H    \
0B5B   anl     p1,#0DCH   | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
0B5D   movx    @r0,a      /
0B5E   mov     r0,#035H   \
0B60   -L0B60:            | ptla opniajca
0B60   djnz    r0,L0B60   /
0B62   anl     p1,#0DCH   \
0B64   orl     p1,#023H   | odczytaj warto z DATA REGISTER do A
0B66   movx    a,@r0      /
0B67   anl     p1,#0DCH   \
0B69   orl     p1,#001H   | zapisz TRACK REGISTER
0B6B   movx    @r0,a      /
0B6C   jmp     L04CC		jeeli to pierwsza poraka -> powtrka, w przeciwnym wypadku koniec operacji

; By Interrupt Request podczas SEEK

0B6E   -L0B6E:
0B6E   anl     p1,#0DCH   \
0B70   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera, ktry nie jest jednak wykorzystany
0B72   movx    a,@r0      /
0B73   orl     p2,#008H		ustawienie omijania rozpoznawania gstoci na ciece 0 podczas operacji odczytu lub zapisu sektora
0B75   mov     a,psw      \
0B76   anl     a,#0F8H    | ustawienie na 3 najmodszych bitach psw liczby prb wykonania operacji na sektorze -1 (cznie bd 3 prby odczytu/zapisu)
0B78   orl     a,#002H    /
0B7A   jmp     L0400		(0C00) - skok do zasadniczej procedury czytajcej albo zapisujcej sektor

; Czytaj, albo zapisz sektor

0C00   -L0C00:
0C00   mov     psw,a		zapisanie przygotowanej w A nowej wartoci psw
0C01   stop    tcnt			zatrzymanie licznika
0C02   jtf     L0C04		wykasowanie flagi przepenienia
0C04   -L0C04:
0C04   clr     a          \ wyzerowanie licznika
0C05   mov     t,a        /
0C06   in      a,p2       \
0C07   anl     a,#007H    | sprawdzenie, czy 3 najmodsze bity w p2 s rwne 001
0C09   xrl     a,#001H    /
0C0B   jz      L0C0F		tak -> wykonaj READ SECTOR
0C0D   jmp     L0500		(D000) - wykonaj WRITE SECTOR

; READ SECTOR . Wynik: [$81-$FF] lub [$1-$FF] + bajt w rejestrze t (pierwszy)

0C0F   -L0C0F:
0C0F   in      a,p2		  \
0C10   rl      a          |
0C11   rl      a          | wpisanie do r0 wartoci 0 dla gstoci Double (DD lub DSDD) lub $80 dla SD i ED
0C12   anl     a,#080H    |
0C14   mov     r0,a	      /
0C15   inc     r0			zwiksz r0 o 1, bdzie $1 lub $81
0C16   mov     r2,#09CH		liczba dopuszczalnych przepenie licznika podczas odczytu. czny czas ok 2.3*3 = 7 sek
0C18   mov     r1,#0FFH		komrka zawierajca pierwszy bajt danych sektora
0C1A   anl     p1,#0DCH   \
0C1C   mov     a,#088H    | zapis do COMMAND REGISTER komendy READ SECTOR (Sigle sector, Disable spin up, No delay)
0C1E   movx    @r0,a      /
0C1F   anl     p1,#0DCH   \ bdzie odczyt z DATA REGISTER kontrolera
0C21   orl     p1,#023H   /
0C23   strt    t			uruchamiamy licznik
0C24   -L0C24:
0C24   jtf     L0CA5		przpenienie licznika -> zmniejsz nr przpeniania
0C26   -L0C26:
0C26   jnt1    L0C24		nie ma Data Requesta -> ciasna ptla
0C28   -L0C28:				JEST PIERWSZY BAJT
0C28   movx    a,@r0      \
0C29   cpl     a          | we bajt danych sektora, zaneguj go i wstaw do pamici
0C2A   mov     @r1,a      /
0C2B   clr     a          \ wyzerowanie timera
0C2C   mov     t,a        /
0C2D   jtf     L0C2F		wyzerowanie flagi przepenienia
0C2F   -L0C2F:
0C2F   jt1     L0C35		jeeli Data Request -> wyskok z ptli
0C31   -L0C31:
0C31   jtf     L0CB7		przepenienie podczas czytania dalszych bajtw -> 0CB7
0C33   -L0C33:
0C33   jnt1    L0C31		nie ma Data Requesta -> ciasna ptla
0C35   -L0C35:
0C35   movx    a,@r0      \ we bajt danych od kontrolera i go dopenij
0C36   cpl     a          /
0C37   mov     @r0,a	  \ zapisz go w pamici i zwiksz o 1 rejestr r0, ktry wskazywa na t komrk
0C38   inc     r0         /
0C39   mov     a,r0			w A bdzie adres nastpnej komrki w stosunku do wanie zapisanej
0C3A   inc     a			A = adres komrki oddalonej o 2 bajty od zapisanej
0C3B   jnz     L0C33		jeeli jest on rny od 0 (nie by to bajt przedostatni) -> kontynuuj ptl
0C3D   -L0C3D:				CZYTAMY OSTATNI BAJT
0C3D   jtf     L0CB7		przepenienie podczas czytania dalszych bajtw -> 0CB7
0C3F   jnt1    L0C3D		nie ma Data Requesta -> ciasna ptla
0C41   movx    a,@r0	  \ odczytaj bajt danych sektora i utwrz jego negacj
0C42   cpl     a          /
0C43   xch     a,@r0		zapisz ostatni bajt. Bajt pierwszy, ktry do tej pory znajdowa si w komrce $FF wskazywanej przez r0 wdruje do A
0C44   mov     r0,a			bajt pierwszy do r0
0C45   in      a,p2       \ czy jest DD lub DSDD?
0C46   cpl     a          /
0C47   jb5     L0C4D		tak -> przeskok (pierwszy bajt zostaje w r0)
0C49   mov     a,r0		  \
0C4A   mov     r0,#080H   | wpisanie pod adresem $80 pierwszego bajtu sektora, ktry do tej pory znajdowa si w r0
0C4C   mov     @r0,a      /
0C4D   -L0C4D:
0C4D   jtf     L0C56		jeeli pierwsze przepenienie -> 0C56
0C4F   in      a,p1       \ czy jest Interrupt Request?
0C50   anl     a,#004H    /
0C52   jnz     L0C66		tak -> 0C66 (finito)
0C54   jmp     L044D		(0C4D) - nie ma, ciasna ptla

0C56   -L0C56:
0C56   jtf     L0C5F		jeeli drugie przepenienie -> 0C5F
0C58   in      a,p1       \ czy jest Interrupt Request?
0C59   anl     a,#004H    /
0C5B   jnz     L0C66		tak -> 0C66 (finito)
0C5D   jmp     L0456		(0C56) - nie ma, ciasna ptla

0C5F   -L0C5F:
0C5F   jtf     L0CB7		jeeli trzecie przepenienie -> 0CB7 (zmiana gstoci)
0C61   in      a,p1		  \ czy jest Interrupt Request?
0C62   anl     a,#004H	  /
0C64   jz      L0C4D		nie -> skok na pocztek ptli oczekujcej na Interrupt Request
0C66   -L0C66:
0C66   stop    tcnt			zatrzymanie licznika
0C67   mov     a,r0       \ pierwszy bajt sektora idzie do t na przechowanie
0C68   mov     t,a        /
0C69   anl     p1,#0DCH   \
0C6B   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
0C6D   movx    a,@r0      /
0C6E   mov     r0,a			STATUS REGISTER do r0
0C6F   in      a,p1		  \
0C70   anl     a,#048H    | jeeli SIDE=1 lub DDEN=1 (SD lub ED) -> sektory o penej dugoci
0C72   jnz     L0C8F      /
0C74   anl     p1,#0DCH   \
0C76   orl     p1,#021H   | odczyt z TRACK REGISTER
0C78   movx    a,@r0      /
0C79   jnz     L0C8F		jeeli numer cieki <> 0 -> sektory o penej dugoci
0C7B   anl     p1,#0DCH   \
0C7D   orl     p1,#022H   | odczyt z SECTOR REGISTER
0C7F   movx    a,@r0      /
0C80   add     a,#0FCH	  \ jeeli po dodaniu $FC nastpi przeniesienie -> pena dugo sektora, gdy mia on numer >= 4
0C82   jc      L0C8F      /
0C84   in      a,p2		  \ jeeli gsto SD lub ED -> pena dugo sektora
0C85   jb5     L0C8B      /
0C87   jmp     L05AB		(0DAB) - przepisz pierwsz poow strony 0 do drugiej poowy, kontynuuj od 0C94
0C89   jmp     L0494

; Usu LOST DATA, sprawd status

0C8B   -L0C8B:
0C8B   mov     a,r0		  \
0C8C   anl     a,#0FBH    | w r0 jest bajt statusu. Usu w num bit LOST DATA (po co?) i przelij z powrotem do r0
0C8E   mov     r0,a       /
0C8F   -L0C8F:
0C8F   in      a,p2		  \
0C90   rl      a          | wpisanie do A wartoci 0 dla gstoci Double (DD lub DSDD) lub $80 dla SD i ED (po co?)
0C91   rl      a          |
0C92   anl     a,#080H    /

; Skontroluj status w r0

0C94   xch     a,r0			wstaw w r0 modszy bajt dugoci sektora a do A status odczytu
0C95   jmp     L04EB		(0CEB) - sprawd status caego odczytu w A

; Chyba rozpoznano gsto

0C97   jb2     L0C9F		jeeli jest DRQ w bajcie statusu (odczytano za mao bajtw) -> zmiana na ED
0C99   jnz     L0CC6		bajt statusu <> 0 -> zmiana gstoci, bd
0C9B   clr     f1			status ok
0C9C   sel     mb0        \
0C9D   jmp     L0300      / skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff

; Przestaw gsto na ED

0C9F   -L0C9F:
0C9F   anl     p2,#0CFH   \ ustaw gsto na ED jeeli byo SD (skutek uboczny: jeeli byo DD, to przestawiamy na DSDD, ale wtedy nie wystpi DRQ za
0CA1   orl     p2,#010H   / pierwszym razem
0CA3   jmp     L04C6		(0CC6) - kolejna prba odczytu

; Przepenienie licznika dla pierwszego bajtu odczytanego z kontrolera

0CA5   -L0CA5:
0CA5   jnt1    L0CA9		nie ma Data Requestu -> przeskok (zmniejszenie licznika ptli)
0CA7   jt1     L0C28		jest Data Request -> odczyt bajtu sektora
0CA9   -L0CA9:
0CA9   djnz    r2,L0C26		zmniejszenie o 1 liczby przepenie licznika i kontynuacja ptli
0CAB   stop    tcnt			zatrzymaj licznik
0CAC   jmp     L04F1		(0CF1) - zmnie gsto na Single jeeli byo DD lub DSDD, Force Interrupt i ponowny odczyt

; Force Interrupt, powtrz 1 raz lub zakocz

0CAE   mov     a,#0D0H	  \ Force Interrupt do kontrolera
0CB0   movx    @r0,a	  /
0CB1   mov     r0,#035H   \
0CB3   -L0CB3:            | ptla opniajca
0CB3   djnz    r0,L0CB3   /
0CB5   jmp     L04CC		(0CCC) odczyt nieudany, powtrz 1 raz lub zakocz

; Przepenienie licznika dla dalszych bajtw odczytanego z kontrolera

0CB7   -L0CB7:
0CB7   stop    tcnt			zatrzymaj licznik
0CB8   in      a,p2		  \ jeeli SD lub ED -> przeskok
0CB9   jb5     L0CBD      /
0CBB   orl     p2,#030H		ustal format ED
0CBD   -L0CBD:
0CBD   anl     p1,#0DCH   \
0CBF   mov     a,#0D0H    | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
0CC1   movx    @r0,a      /
0CC2   mov     r0,#035H   \
0CC4   -L0CC4:            | ptla opniajca
0CC4   djnz    r0,L0CC4   /

; Odczyt nieudany

0CC6   -L0CC6:
0CC6   mov     a,t		  \ odtworzenie w r0 pierwszego bajtu sektora, ktry by przechowywany w t (po co?)
0CC7   mov     r0,a       /
0CC8   mov     a,psw      \ zmniejszenie o 1 przechowywanej na 3 najmodszych bitach psw liczby prb odczytu
0CC9   dec     a          /
0CCA   jb3     L0C00		jeeli bit 3 jest wci ustawiony na 1 -> 0C00 (kolejna prba, bdzie zapis psw)
0CCC   jf1     L0CD5		jeeli F1=1 (byo ju niepowodzenie) -> 0CD5 (niepowodzenie operacji, zakoczenie)
0CCE   cpl     f1			F1=1 (niepowodzenie poprzedniej prby)
0CCF   anl     p1,#0DCH   \ bdzie odczyt z TRACK REGISTER
0CD1   orl     p1,#021H   /
0CD3   jmp     L0192		(0992) - reset kontrolera, prba ponownego odczytu

; Niepowodzenie operacji, zakoczenie

0CD5   -L0CD5:
0CD5   mov     r0,#07BH   \ ustaw w wewntrznym statusie operacji kod oznaczajcy niepowodzenie operacji
0CD7   mov     @r0,#004H  /
0CD9   mov     r0,#001H		jest to domylny numer komrki, od ktrej emitujemy
0CDB   in      a,p2		  \
0CDC   anl     a,#007H    | sprawdzenie, czy trzy najmodsze bity w p2 maj warto 001 (odczyt)
0CDE   xrl     a,#001H    /
0CE0   jnz     L0CE8		nie -> emisja
0CE2   in      a,p2		  \
0CE3   rl      a          |
0CE4   rl      a          | wpisanie do r0 wartoci 0 dla gstoci Double (DD lub DSDD) lub $80 dla SD i ED
0CE5   anl     a,#080H    |
0CE7   mov     r0,a       /
0CE8   -L0CE8:
0CE8   sel     mb0        \
0CE9   jmp     L0300      / skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff

; Sprawd status caego odczytu

0CEB   anl     a,#03CH		w A jest zawarto STATUS REGISTER
0CED   jb3     L0CC6		jeeli wystpi bd DDM,RNF,CRC lub LOST DATA -> odczyt nieudany
0CEF   jmp     L0497		(0C97) - rozpoznano gsto dyskietki

0CF1   in      a,p2       \ jeeli SD lub ED -> Force Interrupt, powtrz 1 raz lub zakocz
0CF2   jb5     L0CF8      /
0CF4   anl     p2,#0CFH   \ ustal gsto na Single Density
0CF6   orl     p2,#020H   /
0CF8   -L0CF8:
0CF8   anl     p1,#0DCH		przygotowanie do zapisu komendy do kontrolera
0CFA   jmp     L04AE		(0CAE) - zrb Force Interrupt, powtrz 1 raz lub zakocz

; WRITE SECTOR. Bajty do wyemitowania zapisane s w pamici od adresu $7F albo $FF (pierwszy bajt) do adresu 1. Ostatni bajt do wyemitowania zapisany jest
; w t.

0D00   in      a,p2	      \
0D01   rl      a          | wpisanie do r0 wartoci 0 dla gstoci Double (DD lub DSDD) lub $80 dla SD i ED
0D02   rl      a          |
0D03   anl     a,#080H    /
0D05   dec     a			zmniejszenie jej o 1, bdzie $7F lub $FF
0D06   xch     a,r0			przelij to do r0, w A zapisz ostatni bajt do wyemitowania
0D07   xch     a,@r0	  \ pobierz pierwszy bajt danych sektora i odwr go. Do komrki o najwyszym adresie zostanie zapisany ostatni bajt do emisji
0D08   cpl     a          /
0D09   mov     r0,a			bajt ten przelij do r0
0D0A   anl     p1,#0DCH   \ zapis do COMMAND REGISTER komendy WRITE SECTOR (Single Sector, Enable spin-up, No-delay,
0D0C   mov     a,#0A2H    | Disable Write Precomp, Write normal Data Address Mark)
0D0E   movx    @r0,a      /
0D0F   anl     p1,#0DCH   \ bdzie zapis do DATA REGISTER kontrolera
0D11   orl     p1,#003H   /
0D13   mov     a,r0			przelij do A pierwszy bajt sektora
0D14   mov     r0,#09CH		ustal czas czekania na ok 2.2sek przy braku Data Requesta
0D16   strt    t			uruchom licznik
0D17   -L0D17:
0D17   jtf     L0D58		jeeli przepenienie timera -> zmniejsz liczb przepenie
0D19   -L0D19:				PIERWSZY BAJT
0D19   jnt1    L0D17		jeeli nie ma Data Requesta -> ciasna ptla
0D1B   -L0D1B:
0D1B   movx    @r0,a		zapisz pierwszy bajt
0D1C   cpl     a			zaneguj go, aby uzyska posta oryginaln
0D1D   xch     a,r0			do r0
0D1E   clr     a		  \	wyzeruj licznik
0D1F   mov     t,a        /
0D20   jtf     L0D22		wyzeruj flag przepenienia
0D22   -L0D22:
0D22   in      a,p2		  \
0D23   rl      a          | wpisanie do A wartoci 0 dla gstoci Double (DD lub DSDD) lub $80 dla SD i ED
0D24   rl      a		  |
0D25   anl     a,#080H    /
0D27   dec     a			bdzie $FF lub $7F w zalenoci od rozmiaru r0
0D28   xch     a,r0			do r0. Oryginalny pierwszy bajt przechodzi do A
0D29   xch     a,@r0		i do (r). Ostatni bajt do emisji zostaje przepisany do A gdy cay czas znajdowa si w ostatniej komrce
0D2A   dec     r0			zmniejsz adres bajtu o 1, bo pierwszy bajt ju wyemitowalimy
0D2B   -L0D2B:
0D2B   xch     a,@r0	  \ we kolejny bajt i go odwr. xch zamae oryginalne miejsce wpisujc tam ostatni bajt do emisji
0D2C   cpl     a          /
0D2D   jt1     L0D33		jeeli Data Request -> zapisz bajt
0D2F   -L0D2F:
0D2F   jtf     L0D81		przepenienie timera -> 0D81
0D31   jnt1    L0D2F		nie ma Data Requesta -> ciasna ptla
0D33   -L0D33:
0D33   movx    @r0,a		zapisz bajt
0D34   cpl     a		  \ odwr bajt i wstaw go do pamici, gdzie by. Ostatni bajt do emisji wraca do A
0D35   xch     a,@r0      /
0D36   djnz    r0,L0D2B		ptla a r0 dojdzie do 0
0D38   mov     r0,a		  \ po wyjciu z ptli w A bdzie znajdowa si ostatni bajt do emisji, ktry odwracamy
0D39   cpl     a          /
0D3A   jt1     L0D40		jeeli jest Data Request -> przelij ostatni bajt
0D3C   -L0D3C:
0D3C   jtf     L0D84		przepenienie timera -> 0D84
0D3E   jnt1    L0D3C		nie ma Data Requesta -> ciasna ptla
0D40   -L0D40:
0D40   movx    @r0,a		wpisz bajt do kontrolera
0D41   -L0D41:
0D41   jtf     L0D84		przepenienie timera -> 0D84
0D43   in      a,p1		  \ czy jest Interrupt Request?
0D44   anl     a,#004H    /
0D46   jz      L0D41		nie -> ciasna ptla
0D48   stop    tcnt			zatrzymaj licznik
0D49   mov     a,r0		  \ ostatni bajt do emisji (nieodwrcony) zapisujemy w t
0D4A   mov     t,a        /
0D4B   anl     p1,#0DCH   \
0D4D   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
0D4F   movx    a,@r0      /
0D50   jb6     L0D9E		jeeli Write Protect -> 0D9E
0D52   anl     a,#014H		sprawdzenie, czy byo BUSY bd LOST DATA
0D54   jz      L0DA9		nie -> sprawd, czy weryfikacja i j wykonaj
0D56   jmp     L04C6		(0CC6) - odczyt nieudany

; Przepenienie przy zapisu 1 bajtu

0D58   -L0D58:
0D58   jnt1    L0D5C		jeeli nie ma Data Requesta -> zmniejszenie o 1 liczby przepenie
0D5A   jt1     L0D1B		jeeli jednak jest Data Request -> zapisz bajt
0D5C   -L0D5C:
0D5C   djnz    r0,L0D19		zmniejsz o 1 liczb przepenie i wr na pocztek ptli pod 0D19
0D5E   stop    tcnt			zatrzymanie licznika
0D5F   cpl     a          \ odtworzenie postaci oryginalnej ppierwszego bajtu i wpisanie jej do r0
0D60   mov     r0,a       /
0D61   in      a,p2	      \
0D62   rl      a          | wpisanie do A wartoci 0 dla gstoci Double (DD lub DSDD) lub $80 dla SD i ED
0D63   rl      a          |
0D64   anl     a,#080H    /
0D66   dec     a			bdzie $FF lub $7F w zalenoci od rozmiaru sektora
0D67   xch     a,r0			do r0. Pierwszy bajt do zapisu do A
0D68   xch     a,@r0		wstaw go pod najwikszym adresem a ostatni bajt do emisji przepisz do A
0D69   mov     t,a			wstaw ostatni bajt do emisji do t odtwarzajc sytuacj pocztkow
0D6A   in      a,p1       \ czy by Interrupt Request?
0D6B   anl     a,#004H    /
0D6D   jz      L0D76		nie -> Force Interrupt
0D6F   anl     p1,#0DCH   \
0D71   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
0D73   movx    a,@r0      /
0D74   jb6     L0D9E		jeeli Write Protect -> 0D9E
0D76   -L0D76:
0D76   anl     p1,#0DCH   \
0D78   mov     a,#0D0H    | zapis do COMMAND REGISTER komendy Force Interrupt (terminate without interrupt)
0D7A   movx    @r0,a      /
0D7B   mov     r0,#035H	  \
0D7D   -L0D7D:            | ptla opniajca
0D7D   djnz    r0,L0D7D   /
0D7F   jmp     L04CC		(0CC6) - odczyt nieudany

; Przepenienie przy zapisie kolejnych bajtw

0D81   -L0D81:
0D81   cpl     a          \ wstaw nadawany bajt do pamici, gdzie by. Ostatni bajt do emisji wpisz do A
0D82   xch     a,@r0      /
0D83   mov     r0,a			ostatni bajt do emisji do r0
0D84   -L0D84:
0D84   stop    tcnt			zatrzymanie licznika
0D85   mov     a,r0       \ wstaw ostatni bajt do emisji do t odtwarzajc sytuacj pocztkow
0D86   mov     t,a        /
0D87   in      a,p1		  \ czy by Interrupt Request?
0D88   anl     a,#004H    /
0D8A   jz      L0D93		nie -> Force Interrupt
0D8C   anl     p1,#0DCH   \
0D8E   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
0D90   movx    a,@r0      /
0D91   jb6     L0D9E		jeeli Write Protect -> 0D9E
0D93   -L0D93:
0D93   anl     p1,#0DCH   \
0D95   mov     a,#0D0H    | zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
0D97   movx    @r0,a      /
0D98   mov     r0,#035H   \
0D9A   -L0D9A:            | ptla opniajca
0D9A   djnz    r0,L0D9A   /
0D9C   jmp     L04C6		(0CC6) - odczyt nieudany

0D9E   -L0D9E:
0D9E   mov     r0,#07BH   \ ustaw w wewntrznym statusie operacji kod oznaczajcy niepowodzenie spowodowane
0DA0   mov     @r0,#00CH  / zabezpieczeniem dyskietki przez zapisem
0DA2   mov     r0,#001H
0DA4   clr     f1		  \ negatywne potwierdzenie
0DA5   cpl     f1         /
0DA6   sel     mb0
0DA7   jmp     L0300        skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff
0DA9   -L0DA9:
0DA9   jmp     L0600	  	(0E00) - weryfikacja sektora

; Przepisz pierwsz poow strony 0 do drugiej poowy. Bajt wpisywany do komrki $80 pobierz z t.

0DAB   mov     a,t	      \ przepisanie ostatniego bajtu sektora do r0. Do A przepisujemy status caego odczytu
0DAC   xch     a,r0       /
0DAD   mov     t,a			status caego odczytu wstawiamy na przechowanie do t
0DAE   clr     a			A=0 (modsze 7 bitw adresu docelowego, ktre zaraz przepiszzemy do r0
0DAF   xch     a,r0			wstawienie do A pierwszego bajtu do przepisania, r0 bdzie zawierao 0 (bo adres docelowy to $80)
0DB0   jmp     L05B7		wpisz (r0) -> [$80] i przepisz [$01-$7F] -> [$81-$7F]

; Przepisz bajty z komrek [$00-$7F] do [$80-$FF]. Z tej procedury jednak korzystamy skaczc do jej rodka.

0DB2   -L0DB2:
0DB2   mov     a,r0       \
0DB3   anl     a,#07FH	  | wykasowanie w r0 najstarszego bajtu
0DB5   mov     r0,a 	  /
0DB6   mov     a,@r0		wzicie do A bajtu wskazywanego przez r0
0DB7   xch     a,r0		  \
0DB8   orl     a,#080H    | wstawienie do r0 najstarszego bajtu
0DBA   xch     a,r0       /
0DBB   mov     @r0,a		zapisanie wartoci z A pod ten adres
0DBC   inc     r0			nastpna komrka
0DBD   mov     a,r0       \ czy dojechalimy do koca strony (jest 0). Nie -> przepisuj dalej
0DBE   jnz     L0DB2      /
0DC0   mov     a,t		  \ przepisanie statusu caego odczytu do r0
0DC1   mov     r0,a       /
0DC2   mov     a,#080H		zapisanie do A dugoci danych
0DC4   jmp     L0494	    (0C94) - skontroluj status caego odczytu w r0

; Weryfikacja

0E00   in      a,p2	      \
0E01   anl     a,#007H    | sprawdzenie, czy trzy najmodsze bity 2 p2 maj warto 011 (zapis z weryfikacj)
0E03   xrl     a,#003H    /
0E05   jnz     L0E6D		nie -> pozytywne potwierdzenie i koniec
0E07   in      a,p2		  \
0E08   rl      a          | wpisanie do A wartoci 0 dla gstoci Double (DD lub DSDD) lub $80 dla SD i ED
0E09   rl      a		  |
0E0A   anl     a,#080H	  /
0E0C   mov     r0,a			do r0
0E0D   dec     r0			w r0 bdzie si znajdowao $FF lub $7F w zalenoci od gstoci
0E0E   rlc     a			zapamitanie w C najstarszego bitu w A: 1 dla SD i ED lub 0 dla DD lub DSDD
0E0F   mov     a,t		  \ pobranie z t ostatniego bajtu danych sektora i zanegowanie go
0E10   cpl     a          /
0E11   xch     a,@r0	  \ wstawienie zanegowanego ostatniego bajtu pod najwyszym indeksem. W A bdzie warto oryginalna (pierwszy bajt).
0E12   cpl     a          /
0E13   dec     r0			zmniejszenie o 1 indeksu do kolejnego bajtu
0E14   -L0E14:
0E14   xch     a,@r0	  \
0E15   cpl     a		  | pobierz biecy bajt, zaneguj go i wstaw do komrki o 1 wikszej
0E16   inc     r0		  | w komrce o 1 mniejszej bdzie pierwszy bajt, w A ostatni bajt
0E17   xch     a,@r0	  /
0E18   dec     r0		  \ ostatni bajt idzie do komrki o 1 mniejszej a do A pierwszy bajt
0E19   xch     a,@r0      /
0E1A   djnz    r0,L0E14		do ostatniego bajtu sektora (pod indeksem 1)
0E1C   mov     r0,a			do r0 wchodzi pierwszy bajt, ktry na samym poczatku zanegowalimy
0E1D   stop    tcnt			zatrzymaj licznik
0E1E   jtf     L0E20		wyzerowanie flagi przerwania
0E20   -L0E20:
0E20   clr     a		  \ wyzerowanie licznika
0E21   mov     t,a        /
0E22   anl     p1,#0DCH   \
0E24   mov     a,#088H	  | zapis do COMMAND REGISTER komendy READ SECTOR (Sigle sector, Disable spin up, No delay)
0E26   movx    @r0,a      /
0E27   anl     p1,#0DCH   \ bdzie odczyt z DATA REGISTER
0E29   orl     p1,#023H   /
0E2B   strt    t			uruchomienie licznika
0E2C   mov     a,#044H		przez tyle przepenie bdziemy czeka na dane (1 sek)
0E2E   -L0E2E:
0E2E   jtf     L0E73		jeeli przepenienie -> bdzie zmniejszanie numeru przepenienia
0E30   -L0E30:
0E30   jnt1    L0E2E		nie ma Data Requesta -> ciasna ptla
0E32   -L0E32:				WERYFIKACJA PIERWSZEGO BAJTU
0E32   movx    a,@r0        wykonaj odczyt z DATA REGISTER
0E33   xrl     a,r0			sprawdzenie, czy pierwszy bajt ma tak warto jak r0
0E34   jnz     L0E7E		nie -> Force Interrupt
0E36   mov     r0,a			pierwszy bajt ok. wyzeruj r0 (A jest zerem po xrl)
0E37   jt1     L0E40		jeeli Data Request -> pobranie bajtu
0E39   -L0E39:
0E39   inc     a			CZEKANIE NA DRUGI BAJT. Zwikszenie o 1 indeksu ptli czekajcej na drugi bajt
0E3A   jt1     L0E40		jeeli Data Request -> pobranie bajtu
0E3C   jz      L0E7E		gdy indeks ptli dojdzie do 0 (przepeneinie) -> Force Interrupt. Czekamy wic przez 256 obrotw na drugi bajt
0E3E   jnt1    L0E39		nie ma Data Requesta -> ciasna ptla
0E40   -L0E40:				DRUGI BAJT
0E40   movx    a,@r0		we drugi bajt sektora od kontrolera
0E41   xch     a,r0		  \ ustalenie adresu drugiej komrki danych sektora
0E42   rrc     a          | w r0 byo 0, wic po rrc bdzie $0 lub $80 w zalenoci od gstoci
0E43   dec     a		  |	po zmniejszeniu o 1 otrzymujemy $FF lub $7F i jest to adres drugiej komrki, bo adres ostatniej to 1
0E44   xch     a,r0       /	adres drugiej komrki do r0
0E45   xrl     a,@r0		sprawdzenie, czy odczytany bajt ma tak sam warto jak ten w r0
0E46   jnz     L0E7E		nie -> Force Interrupt, weryfikacja nieudana
0E48   dec     r0			zmniejsz o 1 wskanik do komrki pamici
0E49   -L0E49:
0E49   jt1     L0E52		KOLEJNE BAJTY. Jeeli Data Request -> pobranie bajtu
0E4B   -L0E4B:
0E4B   inc     a			zwikszenie o 1 indeksu ptli w A, ktry ponownie si wyzerowa po xrl
0E4C   jt1     L0E52		jeeli Data Request -> pobranie bajtu
0E4E   jz      L0E7E		jeeli indeks ptli doszed do 0 (przepenienie, 256 obrt) -> Force Interrupt
0E50   jnt1    L0E4B		nie ma Data Requesta -> ciasna ptla
0E52   -L0E52:
0E52   movx    a,@r0		we bajt
0E53   xrl     a,@r0	  	sprawdzenie, czy jest on taki sam, jak warto w pamici
0E54   jnz     L0E7E     	nie -> Force Interrupt
0E56   djnz    r0,L0E49		ptla a do ostatniego bajtu
0E58   clr     a		  \ wyzerowanie licznika
0E59   mov     t,a        /
0E5A   jtf     L0E5C		wyzerowanie flagi przerwania
0E5C   -L0E5C:
0E5C   jtf     L0E7E		przepenienie licznika -> Force Interrupt
0E5E   in      a,p1		  \ nie byo Interrupt Requesta -> ciasna ptla
0E5F   anl     a,#004H    /
0E61   jz      L0E5C		zatrzymanie licznika
0E63   stop    tcnt
0E64   anl     p1,#0DCH   \
0E66   orl     p1,#020H   | odczyt STATUS REGISTER kontrolera
0E68   movx    a,@r0      /
0E69   anl     a,#03CH    \ jeeli DDM, RNF, CRC lub LOST DATA -> Force Interrupt
0E6B   jnz     L0E7E      /
0E6D   -L0E6D:
0E6D   clr     f1			bdzie pozytywne potwierdzenie
0E6E   mov     r0,#001H
0E70   sel     mb0			bank 0
0E71   jmp     L0300        skok do procedury emitujcej przygotowany bufor od adresu w r0 do $ff

; Przepenienie licznika podczas sprawdzania pierwszego bajtu podczas weryfikacji

0E73   -L0E73:
0E73   jnt1    L0E77		jeeli nie byo Data Requesta -> przeskok (zmniejsz numer przepenienia)
0E75   jt1     L0E32		jeeli Data Request -> odczyt z kontrolera
0E77   -L0E77:
0E77   dec     a			zmniejszenie o 1 liczby dopuszczalnych przepenie
0E78   jnt1    L0E7C		jeeli nie ma Data Requesta -> przeskok
0E7A   jt1     L0E32		jeeli Data Request -> odczyt z kontrolera
0E7C   -L0E7C:
0E7C   jnz     L0E30		jeeli nie doszlimy do ostatniego przepenienia -> kontynuacja czytania
0E7E   -L0E7E:
0E7E   stop    tcnt         zatrzymaj timer
0E7F   mov     a,#0D0H      zapis do COMMAND REGISTER komendy FORCE INTERRUPT (terminate without interrupt)
0E81   anl     p1,#0DCH
0E83   movx    @r0,a
0E84   mov     r0,#035H   \
0E86   -L0E86:            | ptla opniajca
0E86   djnz    r0,L0E86   /
0E88   clr     f1         \ bdzie negatywne potwierdzenie
0E89   cpl     f1         /
0E8A   jmp     L04CC		(0CC6) - odczyt nieudany
